From 6464bb0ae5d2cb774ccd5187f65a6ff83c051ed9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 20 Nov 2001 08:54:15 +0000 Subject: added the beginnings of ADS support in smbd (This used to be commit c7f611691941ca92f57665e19d6e46b161599427) --- source3/libads/ldap.c | 324 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 324 insertions(+) create mode 100644 source3/libads/ldap.c (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c new file mode 100644 index 0000000000..2853dbbaa3 --- /dev/null +++ b/source3/libads/ldap.c @@ -0,0 +1,324 @@ +/* + Unix SMB/Netbios implementation. + Version 3.0 + ads (active directory) utility library + Copyright (C) Andrew Tridgell 2001 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +#ifdef HAVE_ADS + +/* return a dn of the form "dc=AA,dc=BB,dc=CC" from a + realm of the form AA.BB.CC + caller must free +*/ +static char *ads_build_dn(const char *realm) +{ + char *p, *r; + int numdots = 0; + char *ret; + int len; + + r = strdup(realm); + + if (!r || !*r) return r; + + for (p=r; *p; p++) { + if (*p == '.') numdots++; + } + + len = (numdots+1)*4 + strlen(r) + 1; + +ret = malloc(len); + strlcpy(ret,"dc=", len); + p=strtok(r,"."); + strlcat(ret, p, len); + + while ((p=strtok(NULL,"."))) { + strlcat(ret,",dc=", len); + strlcat(ret, p, len); + } + + free(r); + + return ret; +} + +/* + return a string for an error from a ads routine +*/ +char *ads_errstr(int rc) +{ + return ldap_err2string(rc); +} + +/* + initialise a ADS_STRUCT, ready for some ads_ ops +*/ +ADS_STRUCT *ads_init(const char *realm, + const char *ldap_server, + const char *bind_path) +{ + ADS_STRUCT *ads; + + ads = (ADS_STRUCT *)xmalloc(sizeof(*ads)); + memset(ads, 0, sizeof(*ads)); + + ads->realm = realm? strdup(realm) : NULL; + ads->ldap_server = ldap_server? strdup(ldap_server) : NULL; + ads->bind_path = bind_path? strdup(bind_path) : NULL; + ads->ldap_port = LDAP_PORT; + + if (!ads->bind_path) { + ads->bind_path = ads_build_dn(ads->realm); + } + + return ads; +} + + +/* + this is a minimal interact function, just enough for SASL to talk + GSSAPI/kerberos to W2K +*/ +static int sasl_interact(LDAP *ld,unsigned flags,void *defaults,void *in) +{ + sasl_interact_t *interact = in; + + while (interact->id != SASL_CB_LIST_END) { + interact->result = strdup(""); + interact->len = 0; + interact++; + } + + return LDAP_SUCCESS; +} + +/* + connect to the LDAP server +*/ +int ads_connect(ADS_STRUCT *ads) +{ + int version = LDAP_VERSION3; + int rc; + + ads->ld = ldap_open(ads->ldap_server, ads->ldap_port); + if (!ads->ld) { + return errno; + } + ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); + + rc = ldap_sasl_interactive_bind_s(ads->ld, NULL, NULL, NULL, NULL, 0, + sasl_interact, NULL); + + return rc; +} + + +/* + find a machine account given a hostname +*/ +int ads_find_machine_acct(ADS_STRUCT *ads, void **res, const char *host) +{ + int ret; + char *exp; + + /* the easiest way to find a machine account anywhere in the tree + is to look for hostname$ */ + asprintf(&exp, "(samAccountName=%s$)", host); + *res = NULL; + ret = ldap_search_s(ads->ld, ads->bind_path, + LDAP_SCOPE_SUBTREE, exp, NULL, 0, (LDAPMessage **)res); + free(exp); + return ret; +} + + +/* + a convenient routine for adding a generic LDAP record +*/ +int ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ...) +{ + int i; + va_list ap; + LDAPMod **mods; + char *name, *value; + int ret; +#define MAX_MOD_VALUES 10 + + /* count the number of attributes */ + va_start(ap, new_dn); + for (i=0; va_arg(ap, char *); i++) { + /* skip the values */ + while (va_arg(ap, char *)) ; + } + va_end(ap); + + mods = malloc(sizeof(LDAPMod *) * (i+1)); + + va_start(ap, new_dn); + for (i=0; (name=va_arg(ap, char *)); i++) { + char **values; + int j; + values = (char **)malloc(sizeof(char *) * (MAX_MOD_VALUES+1)); + for (j=0; (value=va_arg(ap, char *)) && j < MAX_MOD_VALUES; j++) { + values[j] = value; + } + values[j] = NULL; + mods[i] = malloc(sizeof(LDAPMod)); + mods[i]->mod_type = name; + mods[i]->mod_op = LDAP_MOD_ADD; + mods[i]->mod_values = values; + } + mods[i] = NULL; + va_end(ap); + + ret = ldap_add_s(ads->ld, new_dn, mods); + + for (i=0; mods[i]; i++) { + free(mods[i]->mod_values); + free(mods[i]); + } + free(mods); + + return ret; +} + +/* + add a machine account to the ADS server +*/ +static int ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname) +{ + int ret; + char *host_spn, *host_upn, *new_dn, *samAccountName, *controlstr; + + asprintf(&host_spn, "HOST/%s", hostname); + asprintf(&host_upn, "%s@%s", host_spn, ads->realm); + asprintf(&new_dn, "cn=%s,cn=Computers,%s", hostname, ads->bind_path); + asprintf(&samAccountName, "%s$", hostname); + asprintf(&controlstr, "%u", + UF_DONT_EXPIRE_PASSWD | UF_WORKSTATION_TRUST_ACCOUNT | + UF_TRUSTED_FOR_DELEGATION | UF_USE_DES_KEY_ONLY); + + ret = ads_gen_add(ads, new_dn, + "cn", hostname, NULL, + "sAMAccountName", samAccountName, NULL, + "objectClass", + "top", "person", "organizationalPerson", + "user", "computer", NULL, + "userPrincipalName", host_upn, NULL, + "servicePrincipalName", host_spn, NULL, + "dNSHostName", hostname, NULL, + "userAccountControl", controlstr, NULL, + "operatingSystem", "Samba", NULL, + "operatingSystemVersion", VERSION, NULL, + NULL); + + free(host_spn); + free(host_upn); + free(new_dn); + free(samAccountName); + free(controlstr); + + return ret; +} + +/* + dump a record from LDAP on stdout + used for debugging +*/ +void ads_dump(ADS_STRUCT *ads, void *res) +{ + char *field; + LDAPMessage *msg; + BerElement *b; + char *this_dn; + + for (msg = ldap_first_entry(ads->ld, (LDAPMessage *)res); + msg; msg = ldap_next_entry(ads->ld, msg)) { + this_dn = ldap_get_dn(ads->ld, (LDAPMessage *)res); + if (this_dn) { + printf("Dumping: %s\n", this_dn); + } + ldap_memfree(this_dn); + + for (field = ldap_first_attribute(ads->ld, msg, &b); + field; + field = ldap_next_attribute(ads->ld, msg, b)) { + char **values, **p; + values = ldap_get_values(ads->ld, msg, field); + for (p = values; *p; p++) { + printf("%s: %s\n", field, *p); + } + ldap_value_free(values); + ldap_memfree(field); + } + + ber_free(b, 1); + printf("\n"); + } +} + +/* + count how many replies are in a LDAPMessage +*/ +int ads_count_replies(ADS_STRUCT *ads, void *res) +{ + return ldap_count_entries(ads->ld, (LDAPMessage *)res); +} + +/* + join a machine to a realm, creating the machine account + and setting the machine password +*/ +int ads_join_realm(ADS_STRUCT *ads, const char *hostname) +{ + int rc; + LDAPMessage *res; + char *principal; + + rc = ads_find_machine_acct(ads, (void **)&res, hostname); + if (rc == LDAP_SUCCESS && ads_count_replies(ads, res) == 1) { + DEBUG(0, ("Host account for %s already exists\n", hostname)); + goto set_password; + } + + rc = ads_add_machine_acct(ads, hostname); + if (rc != LDAP_SUCCESS) { + DEBUG(0, ("ads_add_machine_acct: %s\n", ads_errstr(rc))); + return rc; + } + + rc = ads_find_machine_acct(ads, (void **)&res, hostname); + if (rc != LDAP_SUCCESS || ads_count_replies(ads, res) != 1) { + DEBUG(0, ("Host account test failed\n")); + /* hmmm, we need NTSTATUS */ + return -1; + } + +set_password: + asprintf(&principal, "HOST/%s@%s", hostname, ads->realm); +#if 0 + krb5_set_principal_password(principal, ads->ldap_server, hostname, ads->realm); +#endif + free(principal); + + return LDAP_SUCCESS; +} + +#endif -- cgit From 2025ef4c18b0fdf79e493c2c97e32bc38019424b Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 23 Nov 2001 00:08:12 +0000 Subject: Ignore *.po files. (This used to be commit 5d343b40650464ae70037fd6e3fd96a9865fa611) --- source3/libads/.cvsignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 source3/libads/.cvsignore (limited to 'source3/libads') diff --git a/source3/libads/.cvsignore b/source3/libads/.cvsignore new file mode 100644 index 0000000000..ad4b35d213 --- /dev/null +++ b/source3/libads/.cvsignore @@ -0,0 +1 @@ +*.po \ No newline at end of file -- cgit From ad2974cd05b4d08c8b92f505bf95aa8e8533235f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 24 Nov 2001 14:16:41 +0000 Subject: added "net join" command this completes the first stage of the smbd ADS support (This used to be commit 058a5aee901e6609969ef7e1d482a720a84a4a12) --- source3/libads/kerberos.c | 149 +++++++++++++++++++ source3/libads/krb5_setpw.c | 352 ++++++++++++++++++++++++++++++++++++++++++++ source3/libads/ldap.c | 103 +++++++++++-- 3 files changed, 592 insertions(+), 12 deletions(-) create mode 100644 source3/libads/kerberos.c create mode 100644 source3/libads/krb5_setpw.c (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c new file mode 100644 index 0000000000..e4e946f0ce --- /dev/null +++ b/source3/libads/kerberos.c @@ -0,0 +1,149 @@ +/* + Unix SMB/Netbios implementation. + Version 3.0 + kerberos utility library + Copyright (C) Andrew Tridgell 2001 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +#ifdef HAVE_KRB5 + +/* + verify an incoming ticket and parse out the principal name and + authorization_data if available +*/ +NTSTATUS ads_verify_ticket(const DATA_BLOB *ticket, + char **principal, DATA_BLOB *auth_data) +{ + krb5_context context; + krb5_auth_context auth_context = NULL; + krb5_keytab keytab = NULL; + krb5_data packet; + krb5_ticket *tkt = NULL; + krb5_data salt; + krb5_encrypt_block eblock; + int ret; + krb5_keyblock * key; + krb5_principal host_princ; + char *host_princ_s; + extern pstring global_myname; + fstring myname; + char *password_s; + krb5_data password; + + if (!secrets_init()) { + DEBUG(1,("secrets_init failed\n")); + return NT_STATUS_LOGON_FAILURE; + } + + password_s = secrets_fetch_machine_password(); + if (!password_s) { + DEBUG(1,("failed to fetch machine password\n")); + return NT_STATUS_LOGON_FAILURE; + } + + password.data = password_s; + password.length = strlen(password_s); + + ret = krb5_init_context(&context); + if (ret) { + DEBUG(1,("krb5_init_context failed (%s)\n", error_message(ret))); + return NT_STATUS_LOGON_FAILURE; + } + + ret = krb5_set_default_realm(context, lp_realm()); + if (ret) { + DEBUG(1,("krb5_set_default_realm failed (%s)\n", error_message(ret))); + return NT_STATUS_LOGON_FAILURE; + } + + /* this whole process is far more complex than I would + like. We have to go through all this to allow us to store + the secret internally, instead of using /etc/krb5.keytab */ + ret = krb5_auth_con_init(context, &auth_context); + if (ret) { + DEBUG(1,("krb5_auth_con_init failed (%s)\n", error_message(ret))); + return NT_STATUS_LOGON_FAILURE; + } + + fstrcpy(myname, global_myname); + strlower(myname); + asprintf(&host_princ_s, "HOST/%s@%s", myname, lp_realm()); + ret = krb5_parse_name(context, host_princ_s, &host_princ); + if (ret) { + DEBUG(1,("krb5_parse_name(%s) failed (%s)\n", host_princ_s, error_message(ret))); + return NT_STATUS_LOGON_FAILURE; + } + + ret = krb5_principal2salt(context, host_princ, &salt); + if (ret) { + DEBUG(1,("krb5_principal2salt failed (%s)\n", error_message(ret))); + return NT_STATUS_LOGON_FAILURE; + } + + if (!(key = (krb5_keyblock *)malloc(sizeof(*key)))) { + return NT_STATUS_NO_MEMORY; + } + + krb5_use_enctype(context, &eblock, ENCTYPE_DES_CBC_MD5); + + ret = krb5_string_to_key(context, &eblock, key, &password, &salt); + if (ret) { + DEBUG(1,("krb5_string_to_key failed (%s)\n", error_message(ret))); + return NT_STATUS_LOGON_FAILURE; + } + + krb5_auth_con_setuseruserkey(context, auth_context, key); + + packet.length = ticket->length; + packet.data = (krb5_pointer)ticket->data; + +#if 0 + file_save("/tmp/ticket.dat", ticket->data, ticket->length); +#endif + + if ((ret = krb5_rd_req(context, &auth_context, &packet, + NULL, keytab, NULL, &tkt))) { + DEBUG(3,("krb5_rd_req with auth failed (%s)\n", + error_message(ret))); + return NT_STATUS_LOGON_FAILURE; + } + + if (tkt->enc_part2) { + *auth_data = data_blob(tkt->enc_part2->authorization_data[0]->contents, + tkt->enc_part2->authorization_data[0]->length); + } + +#if 0 + if (tkt->enc_part2) { + file_save("/tmp/authdata.dat", + tkt->enc_part2->authorization_data[0]->contents, + tkt->enc_part2->authorization_data[0]->length); + } +#endif + + if ((ret = krb5_unparse_name(context, tkt->enc_part2->client, principal))) { + DEBUG(3,("krb5_unparse_name failed (%s)\n", + error_message(ret))); + return NT_STATUS_LOGON_FAILURE; + } + + return NT_STATUS_OK; +} + +#endif diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c new file mode 100644 index 0000000000..5cb3de1bb5 --- /dev/null +++ b/source3/libads/krb5_setpw.c @@ -0,0 +1,352 @@ +/* + Unix SMB/Netbios implementation. + Version 3.0 + krb5 set password implementation + Copyright (C) Andrew Tridgell 2001 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +#if HAVE_KRB5 + +#define DEFAULT_KPASSWD_PORT 464 +#define KRB5_KPASSWD_VERS_CHANGEPW 1 +#define KRB5_KPASSWD_VERS_SETPW 0xff80 +#define KRB5_KPASSWD_ACCESSDENIED 5 +#define KRB5_KPASSWD_BAD_VERSION 6 + +/* This implements the Kerb password change protocol as specifed in + * kerb-chg-password-02.txt + */ +static DATA_BLOB encode_krb5_setpw(const char *hostname, + const char *realm, const char *password) +{ + ASN1_DATA req; + DATA_BLOB ret; + + memset(&req, 0, sizeof(req)); + + asn1_push_tag(&req, ASN1_SEQUENCE(0)); + asn1_push_tag(&req, ASN1_CONTEXT(0)); + asn1_write_OctetString(&req, password, strlen(password)); + asn1_pop_tag(&req); + + asn1_push_tag(&req, ASN1_CONTEXT(1)); + asn1_push_tag(&req, ASN1_SEQUENCE(0)); + + asn1_push_tag(&req, ASN1_CONTEXT(0)); + asn1_write_Integer(&req, 1); + asn1_pop_tag(&req); + + asn1_push_tag(&req, ASN1_CONTEXT(1)); + asn1_push_tag(&req, ASN1_SEQUENCE(0)); + asn1_write_GeneralString(&req, "HOST"); + asn1_write_GeneralString(&req, hostname); + asn1_pop_tag(&req); + asn1_pop_tag(&req); + asn1_pop_tag(&req); + asn1_pop_tag(&req); + + asn1_push_tag(&req, ASN1_CONTEXT(2)); + asn1_write_GeneralString(&req, realm); + asn1_pop_tag(&req); + asn1_pop_tag(&req); + + ret = data_blob(req.data, req.length); + asn1_free(&req); + + return ret; +} + +static krb5_error_code build_setpw_request(krb5_context context, + krb5_auth_context auth_context, + krb5_data *ap_req, + const char *hostname, + const char *realm, + const char *passwd, + krb5_data *packet) +{ + krb5_error_code ret; + krb5_data cipherpw; + krb5_data encoded_setpw; + krb5_replay_data replay; + char *p; + DATA_BLOB setpw; + + ret = krb5_auth_con_setflags(context, + auth_context,KRB5_AUTH_CONTEXT_DO_SEQUENCE); + if (ret) { + DEBUG(1,("krb5_auth_con_setflags failed (%s)\n", + error_message(ret))); + return ret; + } + + setpw = encode_krb5_setpw(hostname, realm, passwd); + + encoded_setpw.data = setpw.data; + encoded_setpw.length = setpw.length; + + ret = krb5_mk_priv(context, auth_context, + &encoded_setpw, &cipherpw, &replay); + if (ret) { + DEBUG(1,("krb5_mk_priv failed (%s)\n", error_message(ret))); + return ret; + } + + packet->data = (char *)malloc(ap_req->length + cipherpw.length + 6); + + /* see the RFC for details */ + p = packet->data + 2; + RSSVAL(p, 0, 0xff80); p += 2; + RSSVAL(p, 0, ap_req->length); p += 2; + memcpy(p, ap_req->data, ap_req->length); p += ap_req->length; + memcpy(p, cipherpw.data, cipherpw.length); p += cipherpw.length; + packet->length = PTR_DIFF(p,packet->data); + RSSVAL(packet->data, 0, packet->length); + + return 0; +} + +static krb5_error_code parse_setpw_reply(krb5_context context, + krb5_auth_context auth_context, + krb5_data *packet) +{ + krb5_data ap_rep; + char *p; + int vnum, ret, res_code; + krb5_data cipherresult; + krb5_data clearresult; + krb5_ap_rep_enc_part *ap_rep_enc; + krb5_replay_data replay; + + if (packet->length < 4) { + return KRB5KRB_AP_ERR_MODIFIED; + } + + p = packet->data; + + if (packet->data[0] == 0x7e || packet->data[0] == 0x5e) { + /* it's an error packet. We should parse it ... */ + DEBUG(1,("Got error packet 0x%x from kpasswd server\n", + packet->data[0])); + return KRB5KRB_AP_ERR_MODIFIED; + } + + if (RSVAL(p, 0) != packet->length) { + DEBUG(1,("Bad packet length (%d/%d) from kpasswd server\n", + RSVAL(p, 0), packet->length)); + return KRB5KRB_AP_ERR_MODIFIED; + } + + p += 2; + + vnum = RSVAL(p, 0); p += 2; + + if (vnum != KRB5_KPASSWD_VERS_SETPW && vnum != KRB5_KPASSWD_VERS_CHANGEPW) { + DEBUG(1,("Bad vnum (%d) from kpasswd server\n", vnum)); + return KRB5KDC_ERR_BAD_PVNO; + } + + ap_rep.length = RSVAL(p, 0); p += 2; + + if (p + ap_rep.length >= packet->data + packet->length) { + DEBUG(1,("ptr beyond end of packet from kpasswd server\n")); + return KRB5KRB_AP_ERR_MODIFIED; + } + + if (ap_rep.length == 0) { + DEBUG(1,("got unencrypted setpw result?!\n")); + return KRB5KRB_AP_ERR_MODIFIED; + } + + /* verify ap_rep */ + ap_rep.data = p; + p += ap_rep.length; + + ret = krb5_rd_rep(context, auth_context, &ap_rep, &ap_rep_enc); + if (ret) { + DEBUG(1,("failed to rd setpw reply (%s)\n", error_message(ret))); + return KRB5KRB_AP_ERR_MODIFIED; + } + + krb5_free_ap_rep_enc_part(context, ap_rep_enc); + + cipherresult.data = p; + cipherresult.length = (packet->data + packet->length) - p; + + ret = krb5_rd_priv(context, auth_context, &cipherresult, &clearresult, + &replay); + if (ret) { + DEBUG(1,("failed to decrypt setpw reply (%s)\n", error_message(ret))); + return KRB5KRB_AP_ERR_MODIFIED; + } + + if (clearresult.length < 2) { + ret = KRB5KRB_AP_ERR_MODIFIED; + return KRB5KRB_AP_ERR_MODIFIED; + } + + p = clearresult.data; + + res_code = RSVAL(p, 0); + + if ((res_code < KRB5_KPASSWD_SUCCESS) || + (res_code > KRB5_KPASSWD_ACCESSDENIED)) { + return KRB5KRB_AP_ERR_MODIFIED; + } + + return 0; +} + +NTSTATUS krb5_set_password(const char *kdc_host, const char *hostname, + const char *realm, const char *newpw) +{ + krb5_context context; + krb5_auth_context auth_context = NULL; + krb5_principal principal; + char *princ_name; + krb5_creds creds, *credsp; + krb5_ccache ccache; + krb5_data ap_req, chpw_req, chpw_rep; + int ret, sock, addr_len; + struct sockaddr remote_addr, local_addr; + krb5_address local_kaddr, remote_kaddr; + + ret = krb5_init_context(&context); + if (ret) { + DEBUG(1,("Failed to init krb5 context (%s)\n", error_message(ret))); + return NT_STATUS_UNSUCCESSFUL; + } + + ret = krb5_cc_default(context, &ccache); + if (ret) { + DEBUG(1,("Failed to get default creds (%s)\n", error_message(ret))); + return NT_STATUS_UNSUCCESSFUL; + } + + ZERO_STRUCT(creds); + + asprintf(&princ_name, "kadmin/changepw@%s", realm); + ret = krb5_parse_name(context, princ_name, &creds.server); + if (ret) { + DEBUG(1,("Failed to parse kadmin/changepw (%s)\n", error_message(ret))); + return NT_STATUS_UNSUCCESSFUL; + } + free(princ_name); + + asprintf(&princ_name, "HOST/%s@%s", hostname, realm); + ret = krb5_parse_name(context, princ_name, &principal); + if (ret) { + DEBUG(1,("Failed to parse %s (%s)\n", princ_name, error_message(ret))); + return NT_STATUS_UNSUCCESSFUL; + } + free(princ_name); + + krb5_princ_set_realm(context, creds.server, + krb5_princ_realm(context, principal)); + + ret = krb5_cc_get_principal(context, ccache, &creds.client); + if (ret) { + DEBUG(1,("Failed to get principal from ccache (%s)\n", + error_message(ret))); + return NT_STATUS_UNSUCCESSFUL; + } + + ret = krb5_get_credentials(context, 0, ccache, &creds, &credsp); + if (ret) { + DEBUG(1,("krb5_get_credentials failed (%s)\n", error_message(ret))); + return NT_STATUS_UNSUCCESSFUL; + } + + ret = krb5_mk_req_extended(context, &auth_context, AP_OPTS_USE_SUBKEY, + NULL, credsp, &ap_req); + if (ret) { + DEBUG(1,("krb5_mk_req_extended failed (%s)\n", error_message(ret))); + return NT_STATUS_UNSUCCESSFUL; + } + + sock = open_udp_socket(kdc_host, DEFAULT_KPASSWD_PORT); + if (sock == -1) { + DEBUG(1,("failed to open kpasswd socket to %s (%s)\n", + kdc_host, strerror(errno))); + return NT_STATUS_UNSUCCESSFUL; + } + + addr_len = sizeof(remote_addr); + getpeername(sock, &remote_addr, &addr_len); + addr_len = sizeof(local_addr); + getsockname(sock, &local_addr, &addr_len); + + remote_kaddr.addrtype = ADDRTYPE_INET; + remote_kaddr.length = sizeof(((struct sockaddr_in *)&remote_addr)->sin_addr); + remote_kaddr.contents = (char *)&(((struct sockaddr_in *)&remote_addr)->sin_addr); + local_kaddr.addrtype = ADDRTYPE_INET; + local_kaddr.length = sizeof(((struct sockaddr_in *)&local_addr)->sin_addr); + local_kaddr.contents = (char *)&(((struct sockaddr_in *)&local_addr)->sin_addr); + + ret = krb5_auth_con_setaddrs(context, auth_context, &local_kaddr, NULL); + if (ret) { + DEBUG(1,("krb5_auth_con_setaddrs failed (%s)\n", error_message(ret))); + return NT_STATUS_UNSUCCESSFUL; + } + + ret = build_setpw_request(context, auth_context, &ap_req, + hostname, realm, newpw, &chpw_req); + if (ret) { + DEBUG(1,("build_setpw_request failed (%s)\n", error_message(ret))); + return NT_STATUS_UNSUCCESSFUL; + } + + if (write(sock, chpw_req.data, chpw_req.length) != chpw_req.length) { + DEBUG(1,("send of chpw failed (%s)\n", strerror(errno))); + return NT_STATUS_UNSUCCESSFUL; + } + + free(chpw_req.data); + + chpw_rep.length = 1500; + chpw_rep.data = (char *) malloc(chpw_rep.length); + + ret = read(sock, chpw_rep.data, chpw_rep.length); + if (ret < 0) { + DEBUG(1,("recv of chpw reply failed (%s)\n", strerror(errno))); + return NT_STATUS_UNSUCCESSFUL; + } + + close(sock); + chpw_rep.length = ret; + + ret = krb5_auth_con_setaddrs(context, auth_context, NULL,&remote_kaddr); + if (ret) { + DEBUG(1,("krb5_auth_con_setaddrs on reply failed (%s)\n", + error_message(ret))); + return NT_STATUS_UNSUCCESSFUL; + } + + ret = parse_setpw_reply(context, auth_context, &chpw_rep); + free(chpw_rep.data); + + if (ret) { + DEBUG(1,("parse_setpw_reply failed (%s)\n", + error_message(ret))); + return NT_STATUS_UNSUCCESSFUL; + } + + return NT_STATUS_OK; +} + +#endif diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 2853dbbaa3..568e220c0b 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -44,7 +44,7 @@ static char *ads_build_dn(const char *realm) len = (numdots+1)*4 + strlen(r) + 1; -ret = malloc(len); + ret = malloc(len); strlcpy(ret,"dc=", len); p=strtok(r,"."); strlcat(ret, p, len); @@ -67,6 +67,25 @@ char *ads_errstr(int rc) return ldap_err2string(rc); } +/* + find the ldap server from DNS + this won't work till we add a DNS packet parser. Talk about a + lousy resolv interface! +*/ +static char *find_ldap_server(ADS_STRUCT *ads) +{ + char *list = NULL; + + if (ldap_domain2hostlist(ads->realm, &list) == LDAP_SUCCESS) { + char *p; + p = strchr(list, ':'); + if (p) *p = 0; + return list; + } + + return NULL; +} + /* initialise a ADS_STRUCT, ready for some ads_ ops */ @@ -76,7 +95,8 @@ ADS_STRUCT *ads_init(const char *realm, { ADS_STRUCT *ads; - ads = (ADS_STRUCT *)xmalloc(sizeof(*ads)); + ads = (ADS_STRUCT *)malloc(sizeof(*ads)); + if (!ads) return NULL; memset(ads, 0, sizeof(*ads)); ads->realm = realm? strdup(realm) : NULL; @@ -84,17 +104,42 @@ ADS_STRUCT *ads_init(const char *realm, ads->bind_path = bind_path? strdup(bind_path) : NULL; ads->ldap_port = LDAP_PORT; + if (!ads->realm) { + ads->realm = lp_realm(); + } if (!ads->bind_path) { ads->bind_path = ads_build_dn(ads->realm); } + if (!ads->ldap_server) { + ads->ldap_server = find_ldap_server(ads); + } + if (!ads->kdc_server) { + /* assume its the same as LDAP */ + ads->kdc_server = ads->ldap_server? strdup(ads->ldap_server) : NULL; + } return ads; } +/* + free the memory used by the ADS structure initialized with 'ads_init(...)' +*/ +void ads_destroy(ADS_STRUCT *ads) +{ + if (ads->ld) ldap_unbind(ads->ld); + SAFE_FREE(ads->realm); + SAFE_FREE(ads->ldap_server); + SAFE_FREE(ads->kdc_server); + SAFE_FREE(ads->bind_path); + ZERO_STRUCTP(ads); + free(ads); +} /* this is a minimal interact function, just enough for SASL to talk GSSAPI/kerberos to W2K + Error handling is a bit of a problem. I can't see how to get Cyrus-sasl + to give sensible errors */ static int sasl_interact(LDAP *ld,unsigned flags,void *defaults,void *in) { @@ -102,7 +147,7 @@ static int sasl_interact(LDAP *ld,unsigned flags,void *defaults,void *in) while (interact->id != SASL_CB_LIST_END) { interact->result = strdup(""); - interact->len = 0; + interact->len = strlen(interact->result); interact++; } @@ -123,7 +168,8 @@ int ads_connect(ADS_STRUCT *ads) } ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); - rc = ldap_sasl_interactive_bind_s(ads->ld, NULL, NULL, NULL, NULL, 0, + rc = ldap_sasl_interactive_bind_s(ads->ld, NULL, NULL, NULL, NULL, + LDAP_SASL_QUIET, sasl_interact, NULL); return rc; @@ -290,12 +336,11 @@ int ads_join_realm(ADS_STRUCT *ads, const char *hostname) { int rc; LDAPMessage *res; - char *principal; rc = ads_find_machine_acct(ads, (void **)&res, hostname); if (rc == LDAP_SUCCESS && ads_count_replies(ads, res) == 1) { DEBUG(0, ("Host account for %s already exists\n", hostname)); - goto set_password; + return LDAP_SUCCESS; } rc = ads_add_machine_acct(ads, hostname); @@ -311,14 +356,48 @@ int ads_join_realm(ADS_STRUCT *ads, const char *hostname) return -1; } -set_password: - asprintf(&principal, "HOST/%s@%s", hostname, ads->realm); -#if 0 - krb5_set_principal_password(principal, ads->ldap_server, hostname, ads->realm); -#endif - free(principal); + return LDAP_SUCCESS; +} +/* + delete a machine from the realm +*/ +int ads_leave_realm(ADS_STRUCT *ads, const char *hostname) +{ + int rc; + void *res; + char *hostnameDN; + + rc = ads_find_machine_acct(ads, &res, hostname); + if (rc != LDAP_SUCCESS || ads_count_replies(ads, res) != 1) { + DEBUG(0, ("Host account for %s does not exist.\n", hostname)); + return -1; + } + + hostnameDN = ldap_get_dn(ads->ld, (LDAPMessage *)res); + rc = ldap_delete_s(ads->ld, hostnameDN); + ldap_memfree(hostnameDN); + if (rc != LDAP_SUCCESS) { + DEBUG(0, ("ldap_delete_s: %s\n", ads_errstr(rc))); + return rc; + } + + rc = ads_find_machine_acct(ads, &res, hostname); + if (rc == LDAP_SUCCESS && ads_count_replies(ads, res) == 1 ) { + DEBUG(0, ("Failed to remove host account.\n")); + /*hmmm, we need NTSTATUS */ + return -1; + } + return LDAP_SUCCESS; } + +NTSTATUS ads_set_machine_password(ADS_STRUCT *ads, + const char *hostname, + const char *password) +{ + return krb5_set_password(ads->kdc_server, hostname, ads->realm, password); +} + #endif -- cgit From f2e969268d965338338be09d261bde31c5c2ff8b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 25 Nov 2001 00:08:48 +0000 Subject: better auto-selection of realm and ldap server (This used to be commit 69d256af4612f5c1277202eb8a7ef37eb6bb55f4) --- source3/libads/ldap.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 568e220c0b..c3d80a09ec 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -69,8 +69,6 @@ char *ads_errstr(int rc) /* find the ldap server from DNS - this won't work till we add a DNS packet parser. Talk about a - lousy resolv interface! */ static char *find_ldap_server(ADS_STRUCT *ads) { @@ -111,7 +109,10 @@ ADS_STRUCT *ads_init(const char *realm, ads->bind_path = ads_build_dn(ads->realm); } if (!ads->ldap_server) { - ads->ldap_server = find_ldap_server(ads); + ads->ldap_server = lp_ads_server(); + if (!ads->ldap_server[0]) { + ads->ldap_server = find_ldap_server(ads); + } } if (!ads->kdc_server) { /* assume its the same as LDAP */ -- cgit From 3906f9dff6f83e0075ae3d08709a35a629e97fa7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 25 Nov 2001 01:06:56 +0000 Subject: added "net ads status" command (This used to be commit ae0eabd04c97320c2cf3c4575263c53cf61d03ea) --- source3/libads/ldap.c | 91 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 76 insertions(+), 15 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index c3d80a09ec..812c44e7d7 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -285,6 +285,32 @@ static int ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname) return ret; } +/* + dump a binary result from ldap +*/ +static void dump_binary(const char *field, struct berval **values) +{ + int i, j; + for (i=0; values[i]; i++) { + printf("%s: ", field); + for (j=0; jbv_len; j++) { + printf("%02X", (unsigned char)values[i]->bv_val[j]); + } + printf("\n"); + } +} + +/* + dump a string result from ldap +*/ +static void dump_string(const char *field, struct berval **values) +{ + int i; + for (i=0; values[i]; i++) { + printf("%s: %s\n", field, values[i]->bv_val); + } +} + /* dump a record from LDAP on stdout used for debugging @@ -295,6 +321,14 @@ void ads_dump(ADS_STRUCT *ads, void *res) LDAPMessage *msg; BerElement *b; char *this_dn; + struct { + char *name; + void (*handler)(const char *, struct berval **); + } handlers[] = { + {"objectGUID", dump_binary}, + {"objectSid", dump_binary}, + {NULL, NULL} + }; for (msg = ldap_first_entry(ads->ld, (LDAPMessage *)res); msg; msg = ldap_next_entry(ads->ld, msg)) { @@ -307,12 +341,21 @@ void ads_dump(ADS_STRUCT *ads, void *res) for (field = ldap_first_attribute(ads->ld, msg, &b); field; field = ldap_next_attribute(ads->ld, msg, b)) { - char **values, **p; - values = ldap_get_values(ads->ld, msg, field); - for (p = values; *p; p++) { - printf("%s: %s\n", field, *p); + struct berval **values; + int i; + + values = ldap_get_values_len(ads->ld, msg, field); + + for (i=0; handlers[i].name; i++) { + if (StrCaseCmp(handlers[i].name, field) == 0) { + handlers[i].handler(field, values); + break; + } + } + if (!handlers[i].name) { + dump_string(field, values); } - ldap_value_free(values); + ldap_value_free_len(values); ldap_memfree(field); } @@ -337,26 +380,33 @@ int ads_join_realm(ADS_STRUCT *ads, const char *hostname) { int rc; LDAPMessage *res; + char *host; + + /* hostname must be lowercase */ + host = strdup(hostname); + strlower(host); - rc = ads_find_machine_acct(ads, (void **)&res, hostname); + rc = ads_find_machine_acct(ads, (void **)&res, host); if (rc == LDAP_SUCCESS && ads_count_replies(ads, res) == 1) { - DEBUG(0, ("Host account for %s already exists\n", hostname)); + DEBUG(0, ("Host account for %s already exists\n", host)); return LDAP_SUCCESS; } - rc = ads_add_machine_acct(ads, hostname); + rc = ads_add_machine_acct(ads, host); if (rc != LDAP_SUCCESS) { DEBUG(0, ("ads_add_machine_acct: %s\n", ads_errstr(rc))); return rc; } - rc = ads_find_machine_acct(ads, (void **)&res, hostname); + rc = ads_find_machine_acct(ads, (void **)&res, host); if (rc != LDAP_SUCCESS || ads_count_replies(ads, res) != 1) { DEBUG(0, ("Host account test failed\n")); /* hmmm, we need NTSTATUS */ return -1; } + free(host); + return LDAP_SUCCESS; } @@ -367,11 +417,15 @@ int ads_leave_realm(ADS_STRUCT *ads, const char *hostname) { int rc; void *res; - char *hostnameDN; + char *hostnameDN, *host; + + /* hostname must be lowercase */ + host = strdup(hostname); + strlower(host); - rc = ads_find_machine_acct(ads, &res, hostname); + rc = ads_find_machine_acct(ads, &res, host); if (rc != LDAP_SUCCESS || ads_count_replies(ads, res) != 1) { - DEBUG(0, ("Host account for %s does not exist.\n", hostname)); + DEBUG(0, ("Host account for %s does not exist.\n", host)); return -1; } @@ -383,13 +437,15 @@ int ads_leave_realm(ADS_STRUCT *ads, const char *hostname) return rc; } - rc = ads_find_machine_acct(ads, &res, hostname); + rc = ads_find_machine_acct(ads, &res, host); if (rc == LDAP_SUCCESS && ads_count_replies(ads, res) == 1 ) { DEBUG(0, ("Failed to remove host account.\n")); /*hmmm, we need NTSTATUS */ return -1; } - + + free(host); + return LDAP_SUCCESS; } @@ -398,7 +454,12 @@ NTSTATUS ads_set_machine_password(ADS_STRUCT *ads, const char *hostname, const char *password) { - return krb5_set_password(ads->kdc_server, hostname, ads->realm, password); + NTSTATUS ret; + char *host = strdup(hostname); + strlower(host); + ret = krb5_set_password(ads->kdc_server, host, ads->realm, password); + free(host); + return ret; } #endif -- cgit From cb697dd72a51daa14f174fae4fede2b86e7a7fd2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 25 Nov 2001 01:31:07 +0000 Subject: added "net ads user" and "net ads group" commands (This used to be commit f482583139eedb75a23c7a720dca4e8fb7070fd5) --- source3/libads/ldap.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 812c44e7d7..604a11aa5b 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -177,6 +177,19 @@ int ads_connect(ADS_STRUCT *ads) } +/* + do a general ADS search +*/ +int ads_search(ADS_STRUCT *ads, void **res, + const char *exp, + const char **attrs) +{ + *res = NULL; + return ldap_search_s(ads->ld, ads->bind_path, + LDAP_SCOPE_SUBTREE, exp, (char **)attrs, 0, (LDAPMessage **)res); +} + + /* find a machine account given a hostname */ @@ -188,9 +201,7 @@ int ads_find_machine_acct(ADS_STRUCT *ads, void **res, const char *host) /* the easiest way to find a machine account anywhere in the tree is to look for hostname$ */ asprintf(&exp, "(samAccountName=%s$)", host); - *res = NULL; - ret = ldap_search_s(ads->ld, ads->bind_path, - LDAP_SCOPE_SUBTREE, exp, NULL, 0, (LDAPMessage **)res); + ret = ads_search(ads, res, exp, NULL); free(exp); return ret; } @@ -320,7 +331,6 @@ void ads_dump(ADS_STRUCT *ads, void *res) char *field; LDAPMessage *msg; BerElement *b; - char *this_dn; struct { char *name; void (*handler)(const char *, struct berval **); @@ -332,12 +342,6 @@ void ads_dump(ADS_STRUCT *ads, void *res) for (msg = ldap_first_entry(ads->ld, (LDAPMessage *)res); msg; msg = ldap_next_entry(ads->ld, msg)) { - this_dn = ldap_get_dn(ads->ld, (LDAPMessage *)res); - if (this_dn) { - printf("Dumping: %s\n", this_dn); - } - ldap_memfree(this_dn); - for (field = ldap_first_attribute(ads->ld, msg, &b); field; field = ldap_next_attribute(ads->ld, msg, b)) { -- cgit From eec9e8a052407611df223fec982588e7a2bd7f49 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 28 Nov 2001 03:56:30 +0000 Subject: fix a bunch of places where we can double-free a cli structure (This used to be commit e2ba2383c9f679c076749a8f4fccefc3559e37ec) --- source3/libads/ldap.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 604a11aa5b..49e803a49d 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -270,7 +270,7 @@ static int ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname) asprintf(&new_dn, "cn=%s,cn=Computers,%s", hostname, ads->bind_path); asprintf(&samAccountName, "%s$", hostname); asprintf(&controlstr, "%u", - UF_DONT_EXPIRE_PASSWD | UF_WORKSTATION_TRUST_ACCOUNT | + UF_DONT_EXPIRE_PASSWD | UF_WORKSTATION_TRUST_ACCOUNT | UF_TRUSTED_FOR_DELEGATION | UF_USE_DES_KEY_ONLY); ret = ads_gen_add(ads, new_dn, @@ -466,4 +466,17 @@ NTSTATUS ads_set_machine_password(ADS_STRUCT *ads, return ret; } +/* find the update serial number - this is the core of the ldap cache */ +BOOL ads_USN(ADS_STRUCT *ads, unsigned *usn) +{ + const char *attrs[] = {"highestCommittedUSN", NULL}; + int rc; + void *res; + + rc = ldap_search_s(ads->ld, ads->bind_path, + LDAP_SCOPE_BASE, "(objectclass=*)", (char **)attrs, 0, (LDAPMessage *)&res); + if (rc || ads_count_replies(ads, res) != 1) return False; + return False; +} + #endif -- cgit From 3a193f1597741fb630c50290101daf8231337298 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Wed, 28 Nov 2001 19:49:43 +0000 Subject: add .po32 files to ignore list (This used to be commit 5f625f2877fc5132be3030fc6ea9df4d59ecff05) --- source3/libads/.cvsignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/.cvsignore b/source3/libads/.cvsignore index ad4b35d213..5f2a5c4cf7 100644 --- a/source3/libads/.cvsignore +++ b/source3/libads/.cvsignore @@ -1 +1,2 @@ -*.po \ No newline at end of file +*.po +*.po32 -- cgit From f6b962fba37a1ac105301d699708e541ce34d3b4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 28 Nov 2001 23:54:07 +0000 Subject: fixed some krb5 ifdefs (This used to be commit 23ef22f11700bbaa5778a9678a990a2b041fcefe) --- source3/libads/krb5_setpw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 5cb3de1bb5..1c3b15d2a5 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -21,7 +21,7 @@ #include "includes.h" -#if HAVE_KRB5 +#ifdef HAVE_KRB5 #define DEFAULT_KPASSWD_PORT 464 #define KRB5_KPASSWD_VERS_CHANGEPW 1 -- cgit From fe64484824d8169bf66822ebf7f6a9180a238e6e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 29 Nov 2001 06:21:56 +0000 Subject: Make better use of the ads_init() function to get the kerberos relam etc. This allows us to use automagically obtained values in future, and the value from krb5.conf now. Also fix mem leaks etc. Andrew Bartlett (This used to be commit 8f9ce717819235d98a1463f20ac659cb4b4ebbd2) --- source3/libads/ads_struct.c | 182 ++++++++++++++++++++++++++++++++++++++++++++ source3/libads/kerberos.c | 5 +- source3/libads/ldap.c | 103 +------------------------ 3 files changed, 186 insertions(+), 104 deletions(-) create mode 100644 source3/libads/ads_struct.c (limited to 'source3/libads') diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c new file mode 100644 index 0000000000..be0374225b --- /dev/null +++ b/source3/libads/ads_struct.c @@ -0,0 +1,182 @@ +/* + Unix SMB/Netbios implementation. + Version 3.0 + ads (active directory) utility library + Copyright (C) Andrew Tridgell 2001 + Copyright (C) Andrew Bartlett 2001 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +static char *ads_build_dn(const char *realm) +{ + char *p, *r; + int numdots = 0; + char *ret; + int len; + + r = strdup(realm); + + if (!r || !*r) return r; + + for (p=r; *p; p++) { + if (*p == '.') numdots++; + } + + len = (numdots+1)*4 + strlen(r) + 1; + + ret = malloc(len); + strlcpy(ret,"dc=", len); + p=strtok(r,"."); + strlcat(ret, p, len); + + while ((p=strtok(NULL,"."))) { + strlcat(ret,",dc=", len); + strlcat(ret, p, len); + } + + free(r); + + return ret; +} + +#ifdef HAVE_KRB5 + +/* + get the default relm from krb5.conf +*/ +static char *get_default_realm(ADS_STRUCT *ads) +{ + BOOL ret; + krb5_context context; + char *realm; + + ret = krb5_init_context(&context); + if (ret) { + DEBUG(1,("krb5_init_context failed (%s)\n", error_message(ret))); + return NULL; + } + + ret = krb5_get_default_realm(context, &realm); + if (ret) { + DEBUG(1,("krb5_get_default_realm failed (%s)\n", error_message(ret))); + krb5_free_context(context); + return NULL; + } else { + DEBUG(5,("krb5_get_default_realm got (%s)\n", realm)); + } + krb5_free_context(context); + + return realm; +} + +#else +static char *get_default_realm(ADS_STRUCT *ads) +{ + /* We can't do this if we don't have krb5, + but save linking nightmares */ + DEBUG(5,("get_default_realm: not compiled with krb5.\n")); + return NULL; +} + +#endif + +#ifdef HAVE_LDAP +/* + find the ldap server from DNS +*/ +static char *find_ldap_server(ADS_STRUCT *ads) +{ + char *list = NULL; + + if (ldap_domain2hostlist(ads->realm, &list) == LDAP_SUCCESS) { + char *p; + p = strchr(list, ':'); + if (p) *p = 0; + return list; + } + + return NULL; +} + +#else + +static char *find_ldap_server(ADS_STRUCT *ads) +{ + /* Without LDAP this doesn't make much sense */ + return NULL; +} + +#endif + + +/* + initialise a ADS_STRUCT, ready for some ads_ ops +*/ +ADS_STRUCT *ads_init(const char *realm, + const char *ldap_server, + const char *bind_path) +{ + ADS_STRUCT *ads; + + ads = (ADS_STRUCT *)smb_xmalloc(sizeof(*ads)); + memset(ads, 0, sizeof(*ads)); + + ads->realm = realm? strdup(realm) : NULL; + ads->ldap_server = ldap_server? strdup(ldap_server) : NULL; + ads->bind_path = bind_path? strdup(bind_path) : NULL; + ads->ldap_port = LDAP_PORT; + + if (!ads->realm) { + ads->realm = lp_realm(); + if (!ads->realm[0]) { + ads->realm = get_default_realm(ads); + } + } + if (!ads->bind_path) { + ads->bind_path = ads_build_dn(ads->realm); + } + if (!ads->ldap_server) { + ads->ldap_server = lp_ads_server(); + if (!ads->ldap_server[0]) { + ads->ldap_server = find_ldap_server(ads); + } + } + if (!ads->kdc_server) { + /* assume its the same as LDAP */ + ads->kdc_server = ads->ldap_server? strdup(ads->ldap_server) : NULL; + } + + return ads; +} + +/* + free the memory used by the ADS structure initialized with 'ads_init(...)' +*/ +void ads_destroy(ADS_STRUCT **ads) +{ + if (False && (ads) && (*ads)) { + if ((*ads)->ld) ldap_unbind((*ads)->ld); + SAFE_FREE((*ads)->realm); + SAFE_FREE((*ads)->ldap_server); + SAFE_FREE((*ads)->kdc_server); + SAFE_FREE((*ads)->bind_path); + ZERO_STRUCTP(*ads); + SAFE_FREE(*ads); + } +} + diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index e4e946f0ce..a3aa8b1661 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -27,7 +27,7 @@ verify an incoming ticket and parse out the principal name and authorization_data if available */ -NTSTATUS ads_verify_ticket(const DATA_BLOB *ticket, +NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, char **principal, DATA_BLOB *auth_data) { krb5_context context; @@ -66,9 +66,10 @@ NTSTATUS ads_verify_ticket(const DATA_BLOB *ticket, return NT_STATUS_LOGON_FAILURE; } - ret = krb5_set_default_realm(context, lp_realm()); + ret = krb5_set_default_realm(context, ads->realm); if (ret) { DEBUG(1,("krb5_set_default_realm failed (%s)\n", error_message(ret))); + ads_destroy(&ads); return NT_STATUS_LOGON_FAILURE; } diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 49e803a49d..3e24273dc7 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -27,38 +27,6 @@ realm of the form AA.BB.CC caller must free */ -static char *ads_build_dn(const char *realm) -{ - char *p, *r; - int numdots = 0; - char *ret; - int len; - - r = strdup(realm); - - if (!r || !*r) return r; - - for (p=r; *p; p++) { - if (*p == '.') numdots++; - } - - len = (numdots+1)*4 + strlen(r) + 1; - - ret = malloc(len); - strlcpy(ret,"dc=", len); - p=strtok(r,"."); - strlcat(ret, p, len); - - while ((p=strtok(NULL,"."))) { - strlcat(ret,",dc=", len); - strlcat(ret, p, len); - } - - free(r); - - return ret; -} - /* return a string for an error from a ads routine */ @@ -67,75 +35,6 @@ char *ads_errstr(int rc) return ldap_err2string(rc); } -/* - find the ldap server from DNS -*/ -static char *find_ldap_server(ADS_STRUCT *ads) -{ - char *list = NULL; - - if (ldap_domain2hostlist(ads->realm, &list) == LDAP_SUCCESS) { - char *p; - p = strchr(list, ':'); - if (p) *p = 0; - return list; - } - - return NULL; -} - -/* - initialise a ADS_STRUCT, ready for some ads_ ops -*/ -ADS_STRUCT *ads_init(const char *realm, - const char *ldap_server, - const char *bind_path) -{ - ADS_STRUCT *ads; - - ads = (ADS_STRUCT *)malloc(sizeof(*ads)); - if (!ads) return NULL; - memset(ads, 0, sizeof(*ads)); - - ads->realm = realm? strdup(realm) : NULL; - ads->ldap_server = ldap_server? strdup(ldap_server) : NULL; - ads->bind_path = bind_path? strdup(bind_path) : NULL; - ads->ldap_port = LDAP_PORT; - - if (!ads->realm) { - ads->realm = lp_realm(); - } - if (!ads->bind_path) { - ads->bind_path = ads_build_dn(ads->realm); - } - if (!ads->ldap_server) { - ads->ldap_server = lp_ads_server(); - if (!ads->ldap_server[0]) { - ads->ldap_server = find_ldap_server(ads); - } - } - if (!ads->kdc_server) { - /* assume its the same as LDAP */ - ads->kdc_server = ads->ldap_server? strdup(ads->ldap_server) : NULL; - } - - return ads; -} - -/* - free the memory used by the ADS structure initialized with 'ads_init(...)' -*/ -void ads_destroy(ADS_STRUCT *ads) -{ - if (ads->ld) ldap_unbind(ads->ld); - SAFE_FREE(ads->realm); - SAFE_FREE(ads->ldap_server); - SAFE_FREE(ads->kdc_server); - SAFE_FREE(ads->bind_path); - ZERO_STRUCTP(ads); - free(ads); -} - /* this is a minimal interact function, just enough for SASL to talk GSSAPI/kerberos to W2K @@ -474,7 +373,7 @@ BOOL ads_USN(ADS_STRUCT *ads, unsigned *usn) void *res; rc = ldap_search_s(ads->ld, ads->bind_path, - LDAP_SCOPE_BASE, "(objectclass=*)", (char **)attrs, 0, (LDAPMessage *)&res); + LDAP_SCOPE_BASE, "(objectclass=*)", (char **)attrs, 0, (LDAPMessage **)&res); if (rc || ads_count_replies(ads, res) != 1) return False; return False; } -- cgit From 090acb27c3c2fe0562870ed9a1b13158d3d37767 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 29 Nov 2001 06:38:54 +0000 Subject: define LDAP_PORT when not available (This used to be commit 5a5f140f84f4dd377d141e352f4cb7f9bea4fe64) --- source3/libads/ads_struct.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index be0374225b..84c12bf665 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -123,6 +123,9 @@ static char *find_ldap_server(ADS_STRUCT *ads) #endif +#ifndef LDAP_PORT +#define LDAP_PORT 389 +#endif /* initialise a ADS_STRUCT, ready for some ads_ ops -- cgit From 3a921f37b737cab0729cc904e514647406e6f01c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 29 Nov 2001 08:22:45 +0000 Subject: ads->realm must not be NULL perhaps we should just fail ads_init() in this case? (This used to be commit 2a4ce3de6ae8fb833370d1f9d6e5e7193fafa979) --- source3/libads/ads_struct.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index 84c12bf665..4227684375 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -103,6 +103,8 @@ static char *find_ldap_server(ADS_STRUCT *ads) { char *list = NULL; + if (!ads->realm) return NULL; + if (ldap_domain2hostlist(ads->realm, &list) == LDAP_SUCCESS) { char *p; p = strchr(list, ':'); @@ -149,6 +151,7 @@ ADS_STRUCT *ads_init(const char *realm, if (!ads->realm[0]) { ads->realm = get_default_realm(ads); } + if (!ads->realm) ads->realm = strdup(""); } if (!ads->bind_path) { ads->bind_path = ads_build_dn(ads->realm); -- cgit From 2285b99cb1047ea85589ef23d4ca73278a15ee08 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 3 Dec 2001 06:04:18 +0000 Subject: added a basic ADS backend to winbind. More work needed, but at least basic operations work (This used to be commit 88241cab983b2c7db7d477c6c4654694a7a56cd3) --- source3/libads/ldap.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 80 insertions(+), 8 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 3e24273dc7..61d805ab86 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -228,7 +228,7 @@ static void dump_string(const char *field, struct berval **values) void ads_dump(ADS_STRUCT *ads, void *res) { char *field; - LDAPMessage *msg; + void *msg; BerElement *b; struct { char *name; @@ -239,15 +239,14 @@ void ads_dump(ADS_STRUCT *ads, void *res) {NULL, NULL} }; - for (msg = ldap_first_entry(ads->ld, (LDAPMessage *)res); - msg; msg = ldap_next_entry(ads->ld, msg)) { - for (field = ldap_first_attribute(ads->ld, msg, &b); + for (msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) { + for (field = ldap_first_attribute(ads->ld, (LDAPMessage *)msg, &b); field; - field = ldap_next_attribute(ads->ld, msg, b)) { + field = ldap_next_attribute(ads->ld, (LDAPMessage *)msg, b)) { struct berval **values; int i; - values = ldap_get_values_len(ads->ld, msg, field); + values = ldap_get_values_len(ads->ld, (LDAPMessage *)msg, field); for (i=0; handlers[i].name; i++) { if (StrCaseCmp(handlers[i].name, field) == 0) { @@ -365,8 +364,79 @@ NTSTATUS ads_set_machine_password(ADS_STRUCT *ads, return ret; } +/* + pull the first entry from a ADS result +*/ +void *ads_first_entry(ADS_STRUCT *ads, void *res) +{ + return (void *)ldap_first_entry(ads->ld, (LDAPMessage *)res); +} + +/* + pull the next entry from a ADS result +*/ +void *ads_next_entry(ADS_STRUCT *ads, void *res) +{ + return (void *)ldap_next_entry(ads->ld, (LDAPMessage *)res); +} + +/* + pull a single string from a ADS result +*/ +char *ads_pull_string(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, void *msg, const char *field) +{ + char **values; + char *ret; + + values = ldap_get_values(ads->ld, msg, field); + + if (!values || !values[0]) return NULL; + + ret = talloc_strdup(mem_ctx, values[0]); + ldap_value_free(values); + return ret; +} + +/* + pull a single uint32 from a ADS result +*/ +BOOL ads_pull_uint32(ADS_STRUCT *ads, + void *msg, const char *field, uint32 *v) +{ + char **values; + + values = ldap_get_values(ads->ld, msg, field); + + if (!values || !values[0]) return False; + + *v = atoi(values[0]); + ldap_value_free(values); + return True; +} + +/* + pull a single DOM_SID from a ADS result +*/ +BOOL ads_pull_sid(ADS_STRUCT *ads, + void *msg, const char *field, DOM_SID *sid) +{ + struct berval **values; + BOOL ret; + + values = ldap_get_values_len(ads->ld, msg, field); + + if (!values || !values[0]) return False; + + ret = sid_parse(values[0]->bv_val, values[0]->bv_len, sid); + + ldap_value_free_len(values); + return ret; +} + + /* find the update serial number - this is the core of the ldap cache */ -BOOL ads_USN(ADS_STRUCT *ads, unsigned *usn) +BOOL ads_USN(ADS_STRUCT *ads, uint32 *usn) { const char *attrs[] = {"highestCommittedUSN", NULL}; int rc; @@ -375,7 +445,9 @@ BOOL ads_USN(ADS_STRUCT *ads, unsigned *usn) rc = ldap_search_s(ads->ld, ads->bind_path, LDAP_SCOPE_BASE, "(objectclass=*)", (char **)attrs, 0, (LDAPMessage **)&res); if (rc || ads_count_replies(ads, res) != 1) return False; - return False; + return ads_pull_uint32(ads, res, "highestCommittedUSN", usn); } + + #endif -- cgit From 3ec4a4def3f3a98606ad09ca9feaf366bae7fcb2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 4 Dec 2001 12:08:16 +0000 Subject: added ads_search_dn() and ads_pull_sids() (This used to be commit bc83d55f4400cdcdfed44622954f11580b6d2f87) --- source3/libads/ldap.c | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 61d805ab86..50583146c0 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -88,6 +88,18 @@ int ads_search(ADS_STRUCT *ads, void **res, LDAP_SCOPE_SUBTREE, exp, (char **)attrs, 0, (LDAPMessage **)res); } +/* + do a search on a specific DistinguishedName +*/ +int ads_search_dn(ADS_STRUCT *ads, void **res, + const char *dn, + const char **attrs) +{ + *res = NULL; + return ldap_search_s(ads->ld, dn, + LDAP_SCOPE_BASE, "(objectclass=*)", (char **)attrs, 0, (LDAPMessage **)res); +} + /* find a machine account given a hostname @@ -434,6 +446,35 @@ BOOL ads_pull_sid(ADS_STRUCT *ads, return ret; } +/* + pull an array of DOM_SIDs from a ADS result + return the count of SIDs pulled +*/ +int ads_pull_sids(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, + void *msg, const char *field, DOM_SID **sids) +{ + struct berval **values; + BOOL ret; + int count, i; + + values = ldap_get_values_len(ads->ld, msg, field); + + if (!values) return 0; + + for (i=0; values[i]; i++) /* nop */ ; + + (*sids) = talloc(mem_ctx, sizeof(DOM_SID) * i); + + count = 0; + for (i=0; values[i]; i++) { + ret = sid_parse(values[i]->bv_val, values[i]->bv_len, &(*sids)[count]); + if (ret) count++; + } + + ldap_value_free_len(values); + return count; +} + /* find the update serial number - this is the core of the ldap cache */ BOOL ads_USN(ADS_STRUCT *ads, uint32 *usn) @@ -443,7 +484,7 @@ BOOL ads_USN(ADS_STRUCT *ads, uint32 *usn) void *res; rc = ldap_search_s(ads->ld, ads->bind_path, - LDAP_SCOPE_BASE, "(objectclass=*)", (char **)attrs, 0, (LDAPMessage **)&res); + LDAP_SCOPE_BASE, "(objectclass=*)", attrs, 0, (LDAPMessage **)&res); if (rc || ads_count_replies(ads, res) != 1) return False; return ads_pull_uint32(ads, res, "highestCommittedUSN", usn); } -- cgit From 19c0459153bd6f0ea56b84f78725a77bb70be138 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 5 Dec 2001 04:44:34 +0000 Subject: added functions that convert a ads binary blob to a string (for searching on SID) (This used to be commit 31d6d049b30e364e062f108d6f9221bbdc2ebec5) --- source3/libads/ldap.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 50583146c0..34ca2ad04d 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -376,6 +376,45 @@ NTSTATUS ads_set_machine_password(ADS_STRUCT *ads, return ret; } + +/* + return a RFC2254 binary string representation of a buffer + used in filters + caller must free +*/ +char *ads_binary_string(char *buf, int len) +{ + char *s; + int i, j; + const char *hex = "0123456789ABCDEF"; + s = malloc(len * 3 + 1); + if (!s) return NULL; + for (j=i=0;i> 4]; + s[j+2] = hex[((unsigned char)buf[i]) & 0xF]; + j += 3; + } + s[j] = 0; + return s; +} + +/* + return the binary string representation of a DOM_SID + caller must free +*/ +char *ads_sid_binstring(DOM_SID *sid) +{ + char *buf, *s; + int len = sid_size(sid); + buf = malloc(len); + if (!buf) return NULL; + sid_linearize(buf, len, sid); + s = ads_binary_string(buf, len); + free(buf); + return s; +} + /* pull the first entry from a ADS result */ -- cgit From 5f76385e709204151fb9c743ae9d36e0b3df48de Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 5 Dec 2001 06:26:56 +0000 Subject: more memory leak fixes (This used to be commit eb6f0e91ddd2a97a907a569bc60beca99b494884) --- source3/libads/ads_struct.c | 8 ++++---- source3/libads/ldap.c | 8 ++++++++ 2 files changed, 12 insertions(+), 4 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index 4227684375..2d8bf06156 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -139,7 +139,7 @@ ADS_STRUCT *ads_init(const char *realm, ADS_STRUCT *ads; ads = (ADS_STRUCT *)smb_xmalloc(sizeof(*ads)); - memset(ads, 0, sizeof(*ads)); + ZERO_STRUCTP(ads); ads->realm = realm? strdup(realm) : NULL; ads->ldap_server = ldap_server? strdup(ldap_server) : NULL; @@ -147,7 +147,7 @@ ADS_STRUCT *ads_init(const char *realm, ads->ldap_port = LDAP_PORT; if (!ads->realm) { - ads->realm = lp_realm(); + ads->realm = strdup(lp_realm()); if (!ads->realm[0]) { ads->realm = get_default_realm(ads); } @@ -157,7 +157,7 @@ ADS_STRUCT *ads_init(const char *realm, ads->bind_path = ads_build_dn(ads->realm); } if (!ads->ldap_server) { - ads->ldap_server = lp_ads_server(); + ads->ldap_server = strdup(lp_ads_server()); if (!ads->ldap_server[0]) { ads->ldap_server = find_ldap_server(ads); } @@ -175,7 +175,7 @@ ADS_STRUCT *ads_init(const char *realm, */ void ads_destroy(ADS_STRUCT **ads) { - if (False && (ads) && (*ads)) { + if (ads && *ads) { if ((*ads)->ld) ldap_unbind((*ads)->ld); SAFE_FREE((*ads)->realm); SAFE_FREE((*ads)->ldap_server); diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 34ca2ad04d..251a4a6958 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -100,6 +100,14 @@ int ads_search_dn(ADS_STRUCT *ads, void **res, LDAP_SCOPE_BASE, "(objectclass=*)", (char **)attrs, 0, (LDAPMessage **)res); } +/* + free up memory from a ads_search +*/ +void ads_msgfree(ADS_STRUCT *ads, void *msg) +{ + if (!msg) return; + ldap_msgfree(msg); +} /* find a machine account given a hostname -- cgit From 0799c446809a7ae239864e69995849431cd2cb00 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 5 Dec 2001 07:35:57 +0000 Subject: paranoia fixes in based ldap routines for potential memory leaks (This used to be commit 13b933104e1389608e4831ca47dd8106ea0c60a5) --- source3/libads/ldap.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 251a4a6958..5b391f1282 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -446,13 +446,14 @@ char *ads_pull_string(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, void *msg, const char *field) { char **values; - char *ret; + char *ret = NULL; values = ldap_get_values(ads->ld, msg, field); - - if (!values || !values[0]) return NULL; - - ret = talloc_strdup(mem_ctx, values[0]); + if (!values) return NULL; + + if (values[0]) { + ret = talloc_strdup(mem_ctx, values[0]); + } ldap_value_free(values); return ret; } @@ -466,8 +467,11 @@ BOOL ads_pull_uint32(ADS_STRUCT *ads, char **values; values = ldap_get_values(ads->ld, msg, field); - - if (!values || !values[0]) return False; + if (!values) return False; + if (!values[0]) { + ldap_value_free(values); + return False; + } *v = atoi(values[0]); ldap_value_free(values); @@ -481,13 +485,15 @@ BOOL ads_pull_sid(ADS_STRUCT *ads, void *msg, const char *field, DOM_SID *sid) { struct berval **values; - BOOL ret; + BOOL ret = False; values = ldap_get_values_len(ads->ld, msg, field); - if (!values || !values[0]) return False; + if (!values) return False; - ret = sid_parse(values[0]->bv_val, values[0]->bv_len, sid); + if (values[0]) { + ret = sid_parse(values[0]->bv_val, values[0]->bv_len, sid); + } ldap_value_free_len(values); return ret; -- cgit From addea9645d48bc77f88ed3fa724cdd522e2f31ce Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 5 Dec 2001 07:52:44 +0000 Subject: moved the sequence number fetch into the backend, and fetch the sequence number via ldap when using ads (This used to be commit 9a084f0bb91883224ad44e2b76417d10c15cce42) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 5b391f1282..b18e7927ae 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -536,7 +536,7 @@ BOOL ads_USN(ADS_STRUCT *ads, uint32 *usn) int rc; void *res; - rc = ldap_search_s(ads->ld, ads->bind_path, + rc = ldap_search_s(ads->ld, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, 0, (LDAPMessage **)&res); if (rc || ads_count_replies(ads, res) != 1) return False; return ads_pull_uint32(ads, res, "highestCommittedUSN", usn); -- cgit From 5d41807f4d6b80dd1c51ce2764521a2a38c88936 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 5 Dec 2001 09:19:25 +0000 Subject: added timeouts and retries to ldap operations (This used to be commit 4f004eb54d66b6f811cb2f4791da6c70d77f87c2) --- source3/libads/ldap.c | 62 +++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 53 insertions(+), 9 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index b18e7927ae..14fd716058 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -62,6 +62,8 @@ int ads_connect(ADS_STRUCT *ads) int version = LDAP_VERSION3; int rc; + ads->last_attempt = time(NULL); + ads->ld = ldap_open(ads->ldap_server, ads->ldap_port); if (!ads->ld) { return errno; @@ -75,6 +77,50 @@ int ads_connect(ADS_STRUCT *ads) return rc; } +/* + a wrapper around ldap_search_s that retries depending on the error code + this is supposed to catch dropped connections and auto-reconnect +*/ +int ads_search_retry(ADS_STRUCT *ads, const char *bind_path, int scope, const char *exp, + const char **attrs, void **res) +{ + struct timeval timeout; + int rc = -1, rc2; + int count = 3; + + if (!ads->ld && + time(NULL) - ads->last_attempt < ADS_RECONNECT_TIME) { + return LDAP_SERVER_DOWN; + } + + while (count--) { + *res = NULL; + timeout.tv_sec = ADS_SEARCH_TIMEOUT; + timeout.tv_usec = 0; + if (ads->ld) { + rc = ldap_search_ext_s(ads->ld, bind_path, scope, exp, attrs, 0, NULL, NULL, + &timeout, LDAP_NO_LIMIT, (LDAPMessage **)res); + if (rc == 0) return rc; + } + + if (*res) ads_msgfree(ads, *res); + *res = NULL; + DEBUG(1,("Reopening ads connection after error %s\n", ads_errstr(rc))); + if (ads->ld) { + /* we should unbind here, but that seems to trigger openldap bugs :( + ldap_unbind(ads->ld); + */ + } + ads->ld = NULL; + rc2 = ads_connect(ads); + if (rc2) { + DEBUG(1,("ads_search_retry: failed to reconnect (%s)\n", ads_errstr(rc))); + return rc2; + } + } + DEBUG(1,("ads reopen failed after error %s\n", ads_errstr(rc))); + return rc; +} /* do a general ADS search @@ -83,9 +129,7 @@ int ads_search(ADS_STRUCT *ads, void **res, const char *exp, const char **attrs) { - *res = NULL; - return ldap_search_s(ads->ld, ads->bind_path, - LDAP_SCOPE_SUBTREE, exp, (char **)attrs, 0, (LDAPMessage **)res); + return ads_search_retry(ads, ads->bind_path, LDAP_SCOPE_SUBTREE, exp, attrs, res); } /* @@ -95,9 +139,7 @@ int ads_search_dn(ADS_STRUCT *ads, void **res, const char *dn, const char **attrs) { - *res = NULL; - return ldap_search_s(ads->ld, dn, - LDAP_SCOPE_BASE, "(objectclass=*)", (char **)attrs, 0, (LDAPMessage **)res); + return ads_search_retry(ads, dn, LDAP_SCOPE_BASE, "(objectclass=*)", attrs, res); } /* @@ -535,11 +577,13 @@ BOOL ads_USN(ADS_STRUCT *ads, uint32 *usn) const char *attrs[] = {"highestCommittedUSN", NULL}; int rc; void *res; + BOOL ret; - rc = ldap_search_s(ads->ld, "", - LDAP_SCOPE_BASE, "(objectclass=*)", attrs, 0, (LDAPMessage **)&res); + rc = ads_search_retry(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); if (rc || ads_count_replies(ads, res) != 1) return False; - return ads_pull_uint32(ads, res, "highestCommittedUSN", usn); + ret = ads_pull_uint32(ads, res, "highestCommittedUSN", usn); + ads_msgfree(ads, res); + return ret; } -- cgit From 9421ad4a7a900b219f87754bc20fa14f2f22fd35 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 5 Dec 2001 09:46:53 +0000 Subject: added a REALLY gross hack into kerberos_kinit_password so that winbindd can do a kinit this will be removed once we have code that gets a tgt and puts it in a place where cyrus-sasl can see it (This used to be commit 7d94f1b7365215a020d3678d03d820a7d086174f) --- source3/libads/ads_struct.c | 5 ++++- source3/libads/kerberos.c | 21 +++++++++++++++++++++ source3/libads/ldap.c | 4 ++++ 3 files changed, 29 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index 2d8bf06156..83c8f5b404 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -134,7 +134,8 @@ static char *find_ldap_server(ADS_STRUCT *ads) */ ADS_STRUCT *ads_init(const char *realm, const char *ldap_server, - const char *bind_path) + const char *bind_path, + const char *password) { ADS_STRUCT *ads; @@ -145,6 +146,7 @@ ADS_STRUCT *ads_init(const char *realm, ads->ldap_server = ldap_server? strdup(ldap_server) : NULL; ads->bind_path = bind_path? strdup(bind_path) : NULL; ads->ldap_port = LDAP_PORT; + if (password) ads->password = strdup(password); if (!ads->realm) { ads->realm = strdup(lp_realm()); @@ -181,6 +183,7 @@ void ads_destroy(ADS_STRUCT **ads) SAFE_FREE((*ads)->ldap_server); SAFE_FREE((*ads)->kdc_server); SAFE_FREE((*ads)->bind_path); + SAFE_FREE((*ads)->password); ZERO_STRUCTP(*ads); SAFE_FREE(*ads); } diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index a3aa8b1661..1b0de382bd 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -23,6 +23,27 @@ #ifdef HAVE_KRB5 + +/* VERY nasty hack until we have proper kerberos code for this */ +void kerberos_kinit_password(ADS_STRUCT *ads) +{ + char *s; + FILE *f; + extern pstring global_myname; + fstring myname; + fstrcpy(myname, global_myname); + strlower(myname); + asprintf(&s, "kinit 'HOST/%s@%s'", global_myname, ads->realm); + DEBUG(0,("HACK!! Running %s\n", s)); + f = popen(s, "w"); + if (f) { + fprintf(f,"%s\n", ads->password); + fflush(f); + fclose(f); + } + free(s); +} + /* verify an incoming ticket and parse out the principal name and authorization_data if available diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 14fd716058..287ea225a1 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -70,6 +70,10 @@ int ads_connect(ADS_STRUCT *ads) } ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); + if (ads->password) { + kerberos_kinit_password(ads); + } + rc = ldap_sasl_interactive_bind_s(ads->ld, NULL, NULL, NULL, NULL, LDAP_SASL_QUIET, sasl_interact, NULL); -- cgit From 8aa0a817c1c34b840eb68344a062cdbd95a06a68 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 5 Dec 2001 10:14:22 +0000 Subject: handle ldap server down better (This used to be commit 0d85815c992c6ca77ba64dfb2d7538be4684654d) --- source3/libads/ldap.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 287ea225a1..bfa5bbd9df 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -66,11 +66,13 @@ int ads_connect(ADS_STRUCT *ads) ads->ld = ldap_open(ads->ldap_server, ads->ldap_port); if (!ads->ld) { - return errno; + return LDAP_SERVER_DOWN; } ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); if (ads->password) { + /* the machine acct password might have changed */ + ads->password = secrets_fetch_machine_password(); kerberos_kinit_password(ads); } -- cgit From 6194d6a54161931008244766a380e909bb5a8e63 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 5 Dec 2001 10:35:25 +0000 Subject: fix link error (This used to be commit 58e93a8b7de10f60a1e68570f1bdd6e3d8fa44a5) --- source3/libads/ads_struct.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index 83c8f5b404..15cbb328e8 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -178,7 +178,9 @@ ADS_STRUCT *ads_init(const char *realm, void ads_destroy(ADS_STRUCT **ads) { if (ads && *ads) { +#if HAVE_LDAP if ((*ads)->ld) ldap_unbind((*ads)->ld); +#endif SAFE_FREE((*ads)->realm); SAFE_FREE((*ads)->ldap_server); SAFE_FREE((*ads)->kdc_server); -- cgit From 410dfc917f3471aec65c43f5ba421062f64496f4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 5 Dec 2001 10:44:30 +0000 Subject: fixed a minor password memory leak (This used to be commit 5985d7e6eec1eb80d8d7470ee2ceda8981c7410c) --- source3/libads/ldap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index bfa5bbd9df..60f620d2f4 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -72,6 +72,7 @@ int ads_connect(ADS_STRUCT *ads) if (ads->password) { /* the machine acct password might have changed */ + free(ads->password); ads->password = secrets_fetch_machine_password(); kerberos_kinit_password(ads); } -- cgit From d412f66cd82d8b14c8bd8d97f0235296bc8b2d23 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 6 Dec 2001 05:41:53 +0000 Subject: added a propoer kerberos_kinit_password call contribution from remus@snapserver.com thanks! (This used to be commit 3ace8f1fcc27492d26f5ad0c3cdfc63235ca0609) --- source3/libads/kerberos.c | 76 ++++++++++++++++++++++++++++++++++++++++------- source3/libads/ldap.c | 2 +- 2 files changed, 66 insertions(+), 12 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 1b0de382bd..c494016f98 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -23,25 +23,79 @@ #ifdef HAVE_KRB5 +/* + simulate a kinit, putting the tgt in the default cache location + remus@snapserver.com +*/ +int kerberos_kinit_password(const char *principal, const char *password) +{ + krb5_context ctx; + krb5_error_code code = 0; + krb5_ccache cc; + krb5_principal me; + krb5_creds my_creds; + + if ((code = krb5_init_context(&ctx))) + return code; + + if ((code = krb5_cc_default(ctx, &cc))) { + krb5_free_context(ctx); + return code; + } + + if ((code = krb5_parse_name(ctx, principal, &me))) { + krb5_free_context(ctx); + return code; + } + + if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, password, NULL, + NULL, 0, NULL, NULL))) { + krb5_free_principal(ctx, me); + krb5_free_context(ctx); + return code; + } + + if ((code = krb5_cc_initialize(ctx, cc, me))) { + krb5_free_cred_contents(ctx, &my_creds); + krb5_free_principal(ctx, me); + krb5_free_context(ctx); + return code; + } + + if ((code = krb5_cc_store_cred(ctx, cc, &my_creds))) { + krb5_cc_close(ctx, cc); + krb5_free_cred_contents(ctx, &my_creds); + krb5_free_principal(ctx, me); + krb5_free_context(ctx); + return code; + } + + krb5_cc_close(ctx, cc); + krb5_free_cred_contents(ctx, &my_creds); + krb5_free_principal(ctx, me); + krb5_free_context(ctx); + + return 0; +} + -/* VERY nasty hack until we have proper kerberos code for this */ -void kerberos_kinit_password(ADS_STRUCT *ads) + +/* run kinit to setup our ccache */ +int ads_kinit_password(ADS_STRUCT *ads) { char *s; - FILE *f; + int ret; extern pstring global_myname; fstring myname; fstrcpy(myname, global_myname); strlower(myname); - asprintf(&s, "kinit 'HOST/%s@%s'", global_myname, ads->realm); - DEBUG(0,("HACK!! Running %s\n", s)); - f = popen(s, "w"); - if (f) { - fprintf(f,"%s\n", ads->password); - fflush(f); - fclose(f); - } + asprintf(&s, "HOST/%s@%s", global_myname, ads->realm); + ret = kerberos_kinit_password(s, ads->password); free(s); + if (ret) { + DEBUG(1,("kerberos_kinit_password failed: %s\n", error_message(ret))); + } + return ret; } /* diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 60f620d2f4..a7c9265b18 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -74,7 +74,7 @@ int ads_connect(ADS_STRUCT *ads) /* the machine acct password might have changed */ free(ads->password); ads->password = secrets_fetch_machine_password(); - kerberos_kinit_password(ads); + ads_kinit_password(ads); } rc = ldap_sasl_interactive_bind_s(ads->ld, NULL, NULL, NULL, NULL, -- cgit From 44384354d822e8df2495a68c358201a7833b20bb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 6 Dec 2001 07:33:35 +0000 Subject: put the winbindd krb5 credentials cache in the lock directory this prevents it clobbering the users cache (This used to be commit 3de552f365373de85298dbe911143e036805f9ea) --- source3/libads/kerberos.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index c494016f98..19e8ffdc00 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -87,6 +87,10 @@ int ads_kinit_password(ADS_STRUCT *ads) int ret; extern pstring global_myname; fstring myname; + + /* we don't want this to affect the users ccache */ + setenv("KRB5CCNAME", lock_path("winbindd_ccache"), 1); + fstrcpy(myname, global_myname); strlower(myname); asprintf(&s, "HOST/%s@%s", global_myname, ads->realm); -- cgit From 5d378a280f74405fccbadbfb28e1066613c76fd8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 8 Dec 2001 11:18:56 +0000 Subject: added internal sasl/gssapi code. This means we are no longer dependent on cyrus-sasl which makes the code much less fragile. Also added code to auto-determine the server name or realm (This used to be commit 435fdf276a79c2a517adcd7726933aeef3fa924b) --- source3/libads/ads_struct.c | 49 ++---------- source3/libads/kerberos.c | 24 ++++-- source3/libads/ldap.c | 138 ++++++++++++++++---------------- source3/libads/sasl.c | 186 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 279 insertions(+), 118 deletions(-) create mode 100644 source3/libads/sasl.c (limited to 'source3/libads') diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index 15cbb328e8..72f2a32e64 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -22,7 +22,7 @@ #include "includes.h" -static char *ads_build_dn(const char *realm) +char *ads_build_dn(const char *realm) { char *p, *r; int numdots = 0; @@ -54,46 +54,6 @@ static char *ads_build_dn(const char *realm) return ret; } -#ifdef HAVE_KRB5 - -/* - get the default relm from krb5.conf -*/ -static char *get_default_realm(ADS_STRUCT *ads) -{ - BOOL ret; - krb5_context context; - char *realm; - - ret = krb5_init_context(&context); - if (ret) { - DEBUG(1,("krb5_init_context failed (%s)\n", error_message(ret))); - return NULL; - } - - ret = krb5_get_default_realm(context, &realm); - if (ret) { - DEBUG(1,("krb5_get_default_realm failed (%s)\n", error_message(ret))); - krb5_free_context(context); - return NULL; - } else { - DEBUG(5,("krb5_get_default_realm got (%s)\n", realm)); - } - krb5_free_context(context); - - return realm; -} - -#else -static char *get_default_realm(ADS_STRUCT *ads) -{ - /* We can't do this if we don't have krb5, - but save linking nightmares */ - DEBUG(5,("get_default_realm: not compiled with krb5.\n")); - return NULL; -} - -#endif #ifdef HAVE_LDAP /* @@ -151,11 +111,10 @@ ADS_STRUCT *ads_init(const char *realm, if (!ads->realm) { ads->realm = strdup(lp_realm()); if (!ads->realm[0]) { - ads->realm = get_default_realm(ads); + SAFE_FREE(ads->realm); } - if (!ads->realm) ads->realm = strdup(""); } - if (!ads->bind_path) { + if (!ads->bind_path && ads->realm) { ads->bind_path = ads_build_dn(ads->realm); } if (!ads->ldap_server) { @@ -183,9 +142,11 @@ void ads_destroy(ADS_STRUCT **ads) #endif SAFE_FREE((*ads)->realm); SAFE_FREE((*ads)->ldap_server); + SAFE_FREE((*ads)->ldap_server_name); SAFE_FREE((*ads)->kdc_server); SAFE_FREE((*ads)->bind_path); SAFE_FREE((*ads)->password); + SAFE_FREE((*ads)->user_name); ZERO_STRUCTP(*ads); SAFE_FREE(*ads); } diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 19e8ffdc00..521fe0d5eb 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -85,19 +85,29 @@ int ads_kinit_password(ADS_STRUCT *ads) { char *s; int ret; - extern pstring global_myname; - fstring myname; + char *ccache; + + ccache = lock_path("winbindd_ccache"); /* we don't want this to affect the users ccache */ - setenv("KRB5CCNAME", lock_path("winbindd_ccache"), 1); + setenv("KRB5CCNAME", ccache, 1); - fstrcpy(myname, global_myname); - strlower(myname); - asprintf(&s, "HOST/%s@%s", global_myname, ads->realm); + unlink(ccache); + + if (!ads->user_name) { + /* by default use the machine account */ + extern pstring global_myname; + fstring myname; + fstrcpy(myname, global_myname); + strlower(myname); + asprintf(&ads->user_name, "HOST/%s", global_myname); + } + asprintf(&s, "%s@%s", ads->user_name, ads->realm); ret = kerberos_kinit_password(s, ads->password); free(s); if (ret) { - DEBUG(1,("kerberos_kinit_password failed: %s\n", error_message(ret))); + DEBUG(1,("kerberos_kinit_password %s failed: %s\n", + s, error_message(ret))); } return ret; } diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index a7c9265b18..b716966c1b 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -35,25 +35,6 @@ char *ads_errstr(int rc) return ldap_err2string(rc); } -/* - this is a minimal interact function, just enough for SASL to talk - GSSAPI/kerberos to W2K - Error handling is a bit of a problem. I can't see how to get Cyrus-sasl - to give sensible errors -*/ -static int sasl_interact(LDAP *ld,unsigned flags,void *defaults,void *in) -{ - sasl_interact_t *interact = in; - - while (interact->id != SASL_CB_LIST_END) { - interact->result = strdup(""); - interact->len = strlen(interact->result); - interact++; - } - - return LDAP_SUCCESS; -} - /* connect to the LDAP server */ @@ -68,67 +49,38 @@ int ads_connect(ADS_STRUCT *ads) if (!ads->ld) { return LDAP_SERVER_DOWN; } + if (!ads_server_info(ads)) { + DEBUG(1,("Failed to get ldap server info\n")); + return LDAP_SERVER_DOWN; + } + ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); if (ads->password) { - /* the machine acct password might have changed */ - free(ads->password); - ads->password = secrets_fetch_machine_password(); ads_kinit_password(ads); } - rc = ldap_sasl_interactive_bind_s(ads->ld, NULL, NULL, NULL, NULL, - LDAP_SASL_QUIET, - sasl_interact, NULL); - + rc = ads_sasl_bind(ads); return rc; } /* - a wrapper around ldap_search_s that retries depending on the error code - this is supposed to catch dropped connections and auto-reconnect + do a search with a timeout */ -int ads_search_retry(ADS_STRUCT *ads, const char *bind_path, int scope, const char *exp, - const char **attrs, void **res) +int ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, const char *exp, + const char **attrs, void **res) { struct timeval timeout; - int rc = -1, rc2; - int count = 3; - - if (!ads->ld && - time(NULL) - ads->last_attempt < ADS_RECONNECT_TIME) { - return LDAP_SERVER_DOWN; - } - while (count--) { - *res = NULL; - timeout.tv_sec = ADS_SEARCH_TIMEOUT; - timeout.tv_usec = 0; - if (ads->ld) { - rc = ldap_search_ext_s(ads->ld, bind_path, scope, exp, attrs, 0, NULL, NULL, - &timeout, LDAP_NO_LIMIT, (LDAPMessage **)res); - if (rc == 0) return rc; - } + timeout.tv_sec = ADS_SEARCH_TIMEOUT; + timeout.tv_usec = 0; + *res = NULL; - if (*res) ads_msgfree(ads, *res); - *res = NULL; - DEBUG(1,("Reopening ads connection after error %s\n", ads_errstr(rc))); - if (ads->ld) { - /* we should unbind here, but that seems to trigger openldap bugs :( - ldap_unbind(ads->ld); - */ - } - ads->ld = NULL; - rc2 = ads_connect(ads); - if (rc2) { - DEBUG(1,("ads_search_retry: failed to reconnect (%s)\n", ads_errstr(rc))); - return rc2; - } - } - DEBUG(1,("ads reopen failed after error %s\n", ads_errstr(rc))); - return rc; + return ldap_search_ext_s(ads->ld, + bind_path, scope, + exp, attrs, 0, NULL, NULL, + &timeout, LDAP_NO_LIMIT, (LDAPMessage **)res); } - /* do a general ADS search */ @@ -136,7 +88,8 @@ int ads_search(ADS_STRUCT *ads, void **res, const char *exp, const char **attrs) { - return ads_search_retry(ads, ads->bind_path, LDAP_SCOPE_SUBTREE, exp, attrs, res); + return ads_do_search(ads, ads->bind_path, LDAP_SCOPE_SUBTREE, + exp, attrs, res); } /* @@ -146,7 +99,7 @@ int ads_search_dn(ADS_STRUCT *ads, void **res, const char *dn, const char **attrs) { - return ads_search_retry(ads, dn, LDAP_SCOPE_BASE, "(objectclass=*)", attrs, res); + return ads_do_search(ads, dn, LDAP_SCOPE_BASE, "(objectclass=*)", attrs, res); } /* @@ -586,7 +539,7 @@ BOOL ads_USN(ADS_STRUCT *ads, uint32 *usn) void *res; BOOL ret; - rc = ads_search_retry(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); + rc = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); if (rc || ads_count_replies(ads, res) != 1) return False; ret = ads_pull_uint32(ads, res, "highestCommittedUSN", usn); ads_msgfree(ads, res); @@ -594,5 +547,56 @@ BOOL ads_USN(ADS_STRUCT *ads, uint32 *usn) } +/* find the servers name and realm - this can be done before authentication + The ldapServiceName field on w2k looks like this: + vnet3.home.samba.org:win2000-vnet3$@VNET3.HOME.SAMBA.ORG +*/ +BOOL ads_server_info(ADS_STRUCT *ads) +{ + const char *attrs[] = {"ldapServiceName", NULL}; + int rc; + void *res; + char **values; + char *ret, *p; + + rc = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); + if (rc || ads_count_replies(ads, res) != 1) return False; + + values = ldap_get_values(ads->ld, res, "ldapServiceName"); + + if (!values || !values[0]) return False; + + p = strchr(values[0], ':'); + if (!p) { + ldap_value_free(values); + ldap_msgfree(res); + return False; + } + + SAFE_FREE(ads->ldap_server_name); + + ads->ldap_server_name = strdup(p+1); + p = strchr(ads->ldap_server_name, '$'); + if (!p || p[1] != '@') { + ldap_value_free(values); + ldap_msgfree(res); + SAFE_FREE(ads->ldap_server_name); + return False; + } + + *p = 0; + + /* in case the realm isn't configured in smb.conf */ + if (!ads->realm || !ads->realm[0]) { + SAFE_FREE(ads->realm); + SAFE_FREE(ads->bind_path); + ads->realm = strdup(p+2); + ads->bind_path = ads_build_dn(ads->realm); + } + + DEBUG(3,("got ldap server name %s@%s\n", ret, ads->realm)); + + return True; +} #endif diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c new file mode 100644 index 0000000000..dd948b5d4d --- /dev/null +++ b/source3/libads/sasl.c @@ -0,0 +1,186 @@ +/* + Unix SMB/Netbios implementation. + Version 3.0 + ads sasl code + Copyright (C) Andrew Tridgell 2001 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +#ifdef HAVE_ADS + +#if USE_CYRUS_SASL +/* + this is a minimal interact function, just enough for SASL to talk + GSSAPI/kerberos to W2K + Error handling is a bit of a problem. I can't see how to get Cyrus-sasl + to give sensible errors +*/ +static int sasl_interact(LDAP *ld,unsigned flags,void *defaults,void *in) +{ + sasl_interact_t *interact = in; + + while (interact->id != SASL_CB_LIST_END) { + interact->result = strdup(""); + interact->len = strlen(interact->result); + interact++; + } + + return LDAP_SUCCESS; +} +#endif + + +#define MAX_GSS_PASSES 3 + +/* this performs a SASL/gssapi bind + we avoid using cyrus-sasl to make Samba more robust. cyrus-sasl + is very dependent on correctly configured DNS whereas + this routine is much less fragile + see RFC2078 for details +*/ +int ads_sasl_gssapi_bind(ADS_STRUCT *ads) +{ + int rc, minor_status; + gss_name_t serv_name; + gss_buffer_desc input_name; + gss_ctx_id_t context_handle; + gss_OID mech_type = GSS_C_NULL_OID; + gss_buffer_desc output_token, input_token; + OM_uint32 ret_flags, conf_state; + struct berval cred; + struct berval *scred; + int i=0; + int gss_rc; + uint8 *p; + uint32 max_msg_size; + char *sname; + + asprintf(&sname, "ldap@%s.%s", ads->ldap_server_name, ads->realm); + + input_name.value = sname; + input_name.length = strlen(input_name.value); + + rc = gss_import_name(&minor_status,&input_name,gss_nt_service_name, &serv_name); + + free(sname); + + context_handle = GSS_C_NO_CONTEXT; + + input_token.value = NULL; + input_token.length = 0; + + for (i=0; i < MAX_GSS_PASSES; i++) { + gss_rc = gss_init_sec_context(&minor_status, + GSS_C_NO_CREDENTIAL, + &context_handle, + serv_name, + mech_type, + GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG, + 0, + NULL, + &input_token, + NULL, + &output_token, + &ret_flags, + NULL); + + if (input_token.value) { + gss_release_buffer(&minor_status, &input_token); + } + + if (gss_rc && gss_rc != GSS_S_CONTINUE_NEEDED) goto failed; + + cred.bv_val = output_token.value; + cred.bv_len = output_token.length; + + rc = ldap_sasl_bind_s(ads->ld, NULL, "GSSAPI", &cred, NULL, NULL, + &scred); + + if (output_token.value) { + gss_release_buffer(&minor_status, &output_token); + } + + if (scred) { + input_token.value = scred->bv_val; + input_token.length = scred->bv_len; + } else { + input_token.value = NULL; + input_token.length = 0; + } + + if (gss_rc != GSS_S_CONTINUE_NEEDED) break; + } + + gss_release_name(&minor_status, &serv_name); + + gss_rc = gss_unwrap(&minor_status,context_handle,&input_token,&output_token, + &conf_state,NULL); + + gss_release_buffer(&minor_status, &input_token); + + p = (uint8 *)output_token.value; + + max_msg_size = (p[1]<<16) | (p[2]<<8) | p[3]; + + gss_release_buffer(&minor_status, &output_token); + + output_token.value = malloc(strlen(ads->bind_path) + 8); + p = output_token.value; + + *p++ = 1; /* no sign or seal */ + /* choose the same size as the server gave us */ + *p++ = max_msg_size>>16; + *p++ = max_msg_size>>8; + *p++ = max_msg_size; + snprintf(p, strlen(ads->bind_path)+1, "dn:%s", ads->bind_path); + p += strlen(ads->bind_path); + + output_token.length = strlen(ads->bind_path) + 8; + + gss_rc = gss_wrap(&minor_status, context_handle,0,GSS_C_QOP_DEFAULT, + &output_token, &conf_state, + &input_token); + + free(output_token.value); + + cred.bv_val = input_token.value; + cred.bv_len = input_token.length; + + rc = ldap_sasl_bind_s(ads->ld, NULL, "GSSAPI", &cred, NULL, NULL, + &scred); + + gss_release_buffer(&minor_status, &input_token); + return rc; + +failed: + return gss_rc; +} + +int ads_sasl_bind(ADS_STRUCT *ads) +{ +#if USE_CYRUS_SASL + return ldap_sasl_interactive_bind_s(ads->ld, NULL, NULL, NULL, NULL, + LDAP_SASL_QUIET, + sasl_interact, NULL); +#else + return ads_sasl_gssapi_bind(ads); +#endif +} + +#endif + -- cgit From 35eb6be4ea1b52e2f6028c979ead952a2f96f99d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 8 Dec 2001 12:00:27 +0000 Subject: fix a DEBUG() line (This used to be commit 18da530293b11d895c62d08895ee1f77d8f97a12) --- source3/libads/ldap.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index b716966c1b..c81f2474ae 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -557,7 +557,7 @@ BOOL ads_server_info(ADS_STRUCT *ads) int rc; void *res; char **values; - char *ret, *p; + char *p; rc = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); if (rc || ads_count_replies(ads, res) != 1) return False; @@ -594,7 +594,8 @@ BOOL ads_server_info(ADS_STRUCT *ads) ads->bind_path = ads_build_dn(ads->realm); } - DEBUG(3,("got ldap server name %s@%s\n", ret, ads->realm)); + DEBUG(3,("got ldap server name %s@%s\n", + ads->ldap_server_name, ads->realm)); return True; } -- cgit From bc26ea1e5c712aeef3091c0d3442b7dc430da74c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 9 Dec 2001 00:45:51 +0000 Subject: fixed used of string after free (This used to be commit f7ead035ebe55e94cdd5807b173bd4612866b06f) --- source3/libads/kerberos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 521fe0d5eb..64eca2c8c4 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -104,11 +104,11 @@ int ads_kinit_password(ADS_STRUCT *ads) } asprintf(&s, "%s@%s", ads->user_name, ads->realm); ret = kerberos_kinit_password(s, ads->password); - free(s); if (ret) { DEBUG(1,("kerberos_kinit_password %s failed: %s\n", s, error_message(ret))); } + free(s); return ret; } -- cgit From e051c2c430f706835f250b10cc63e5621054b5ec Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 10 Dec 2001 00:39:01 +0000 Subject: make sid_binstring available without HAVE_ADS (This used to be commit 4a6d29768665f71b72cf48ee34ee9a9c451232f6) --- source3/libads/ldap.c | 39 --------------------------------------- 1 file changed, 39 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index c81f2474ae..2fe97ebb1a 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -386,45 +386,6 @@ NTSTATUS ads_set_machine_password(ADS_STRUCT *ads, return ret; } - -/* - return a RFC2254 binary string representation of a buffer - used in filters - caller must free -*/ -char *ads_binary_string(char *buf, int len) -{ - char *s; - int i, j; - const char *hex = "0123456789ABCDEF"; - s = malloc(len * 3 + 1); - if (!s) return NULL; - for (j=i=0;i> 4]; - s[j+2] = hex[((unsigned char)buf[i]) & 0xF]; - j += 3; - } - s[j] = 0; - return s; -} - -/* - return the binary string representation of a DOM_SID - caller must free -*/ -char *ads_sid_binstring(DOM_SID *sid) -{ - char *buf, *s; - int len = sid_size(sid); - buf = malloc(len); - if (!buf) return NULL; - sid_linearize(buf, len, sid); - s = ads_binary_string(buf, len); - free(buf); - return s; -} - /* pull the first entry from a ADS result */ -- cgit From 3d27d7b9f79d530d7652106332a21e3595b7c812 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 10 Dec 2001 22:10:31 +0000 Subject: moved ccache location change into winbindd code (This used to be commit be254eb13c4bf316823ed43db3ef9407f45ca23b) --- source3/libads/kerberos.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 64eca2c8c4..8fcc32b363 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -85,14 +85,6 @@ int ads_kinit_password(ADS_STRUCT *ads) { char *s; int ret; - char *ccache; - - ccache = lock_path("winbindd_ccache"); - - /* we don't want this to affect the users ccache */ - setenv("KRB5CCNAME", ccache, 1); - - unlink(ccache); if (!ads->user_name) { /* by default use the machine account */ -- cgit From 66d964c9fca128d2e77e0cb1b704b25ab55b45ce Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 11 Dec 2001 05:15:52 +0000 Subject: allow overriding the local time in kerberos_kinit_password() (This used to be commit cb9dbcef7cba9eb42f7b30b81c35142dc945d84f) --- source3/libads/kerberos.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 8fcc32b363..5d7b08a348 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -27,7 +27,8 @@ simulate a kinit, putting the tgt in the default cache location remus@snapserver.com */ -int kerberos_kinit_password(const char *principal, const char *password) +int kerberos_kinit_password(const char *principal, const char *password, + time_t real_time) { krb5_context ctx; krb5_error_code code = 0; @@ -38,6 +39,10 @@ int kerberos_kinit_password(const char *principal, const char *password) if ((code = krb5_init_context(&ctx))) return code; + if (real_time) { + krb5_set_real_time(ctx, real_time, 0); + } + if ((code = krb5_cc_default(ctx, &cc))) { krb5_free_context(ctx); return code; @@ -95,7 +100,8 @@ int ads_kinit_password(ADS_STRUCT *ads) asprintf(&ads->user_name, "HOST/%s", global_myname); } asprintf(&s, "%s@%s", ads->user_name, ads->realm); - ret = kerberos_kinit_password(s, ads->password); + ret = kerberos_kinit_password(s, ads->password, 0); + if (ret) { DEBUG(1,("kerberos_kinit_password %s failed: %s\n", s, error_message(ret))); -- cgit From 75a6ac48a0a2fb5285fd7d92fed770cacc0d400f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 13 Dec 2001 11:29:49 +0000 Subject: try the PDC for our workgroup if we can't find the ldap server (This used to be commit fc9fd2ca19899e757a6d3ccbba3d4a10f27d7a3f) --- source3/libads/ads_struct.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index 72f2a32e64..4b2ab5b40f 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -62,16 +62,21 @@ char *ads_build_dn(const char *realm) static char *find_ldap_server(ADS_STRUCT *ads) { char *list = NULL; + struct in_addr ip; - if (!ads->realm) return NULL; - - if (ldap_domain2hostlist(ads->realm, &list) == LDAP_SUCCESS) { + if (ads->realm && + ldap_domain2hostlist(ads->realm, &list) == LDAP_SUCCESS) { char *p; p = strchr(list, ':'); if (p) *p = 0; return list; } + /* get desperate, find the domain controller IP */ + if (resolve_name(lp_workgroup(), &ip, 0x1B)) { + return strdup(inet_ntoa(ip)); + } + return NULL; } -- cgit From d58b1b5981652e5ef37eb8d07ae3ff7797b112c5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 13 Dec 2001 11:30:13 +0000 Subject: better error handling (This used to be commit ed6279481bfcb21212e9c22009969c19ea4f1646) --- source3/libads/kerberos.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 5d7b08a348..8378442885 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -35,7 +35,12 @@ int kerberos_kinit_password(const char *principal, const char *password, krb5_ccache cc; krb5_principal me; krb5_creds my_creds; - + + if (! *password) { + /* kerberos dies on an empty password! */ + return KRB5_PARSE_MALFORMED; + } + if ((code = krb5_init_context(&ctx))) return code; @@ -103,7 +108,7 @@ int ads_kinit_password(ADS_STRUCT *ads) ret = kerberos_kinit_password(s, ads->password, 0); if (ret) { - DEBUG(1,("kerberos_kinit_password %s failed: %s\n", + DEBUG(0,("kerberos_kinit_password %s failed: %s\n", s, error_message(ret))); } free(s); -- cgit From 48c45486e3e67b96c7ea4c7044823274e9fa72e7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 17 Dec 2001 11:16:22 +0000 Subject: allow selection of the organisational unit when joining a realm (This used to be commit f1231c2b54cac9d4fda7fa9d45fd329f1fd7b779) --- source3/libads/ldap.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 2fe97ebb1a..09498b4384 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -181,14 +181,14 @@ int ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ...) /* add a machine account to the ADS server */ -static int ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname) +static int ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, const char *org_unit) { int ret; char *host_spn, *host_upn, *new_dn, *samAccountName, *controlstr; asprintf(&host_spn, "HOST/%s", hostname); asprintf(&host_upn, "%s@%s", host_spn, ads->realm); - asprintf(&new_dn, "cn=%s,cn=Computers,%s", hostname, ads->bind_path); + asprintf(&new_dn, "cn=%s,cn=%s,%s", hostname, org_unit, ads->bind_path); asprintf(&samAccountName, "%s$", hostname); asprintf(&controlstr, "%u", UF_DONT_EXPIRE_PASSWD | UF_WORKSTATION_TRUST_ACCOUNT | @@ -300,7 +300,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) join a machine to a realm, creating the machine account and setting the machine password */ -int ads_join_realm(ADS_STRUCT *ads, const char *hostname) +int ads_join_realm(ADS_STRUCT *ads, const char *hostname, const char *org_unit) { int rc; LDAPMessage *res; @@ -316,7 +316,7 @@ int ads_join_realm(ADS_STRUCT *ads, const char *hostname) return LDAP_SUCCESS; } - rc = ads_add_machine_acct(ads, host); + rc = ads_add_machine_acct(ads, host, org_unit); if (rc != LDAP_SUCCESS) { DEBUG(0, ("ads_add_machine_acct: %s\n", ads_errstr(rc))); return rc; -- cgit From a062e58d9e47f95ac7c66668b3cfe1f72386f6e0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 19 Dec 2001 08:44:23 +0000 Subject: - added initial support for trusted domains in winbindd_ads - gss error code patch from a.bokovoy@sam-solutions.net - better sid dumping in ads_dump - fixed help in wbinfo (This used to be commit ee1c3e1f044b4ef62169ad74c5cac40eef81bfda) --- source3/libads/ads_struct.c | 26 +++++++++++++++ source3/libads/ldap.c | 77 ++++++++++++++++++++++++++++++++++++++++----- source3/libads/sasl.c | 53 +++++++++++++++++++++---------- 3 files changed, 131 insertions(+), 25 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index 4b2ab5b40f..a7c8d1a681 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -157,3 +157,29 @@ void ads_destroy(ADS_STRUCT **ads) } } + +static void ads_display_status_helper(char *m, OM_uint32 code, int type) +{ + int maj_stat, min_stat; + gss_buffer_desc msg; + int msg_ctx; + + msg_ctx = 0; + while (1) { + maj_stat = gss_display_status(&min_stat, code, + type, GSS_C_NULL_OID, + &msg_ctx, &msg); + DEBUG(1, ("GSS-API error %s: %s\n", m, + (char *)msg.value)); + (void) gss_release_buffer(&min_stat, &msg); + + if (!msg_ctx) + break; + } +} + +void ads_display_status(char * msg, int maj_stat,int min_stat) +{ + ads_display_status_helper(msg, maj_stat, GSS_C_GSS_CODE); + ads_display_status_helper(msg, min_stat, GSS_C_MECH_CODE); +} diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 09498b4384..b41a864ae2 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -38,20 +38,24 @@ char *ads_errstr(int rc) /* connect to the LDAP server */ -int ads_connect(ADS_STRUCT *ads) +ADS_RETURN_CODE ads_connect(ADS_STRUCT *ads) { int version = LDAP_VERSION3; - int rc; + ADS_RETURN_CODE rc; + + rc.error_type = False; ads->last_attempt = time(NULL); ads->ld = ldap_open(ads->ldap_server, ads->ldap_port); if (!ads->ld) { - return LDAP_SERVER_DOWN; + rc.rc = LDAP_SERVER_DOWN; + return rc; } if (!ads_server_info(ads)) { DEBUG(1,("Failed to get ldap server info\n")); - return LDAP_SERVER_DOWN; + rc.rc = LDAP_SERVER_DOWN; + return rc; } ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); @@ -232,6 +236,19 @@ static void dump_binary(const char *field, struct berval **values) } } +/* + dump a sid result from ldap +*/ +static void dump_sid(const char *field, struct berval **values) +{ + int i; + for (i=0; values[i]; i++) { + DOM_SID sid; + sid_parse(values[i]->bv_val, values[i]->bv_len, &sid); + printf("%s: %s\n", field, sid_string_static(&sid)); + } +} + /* dump a string result from ldap */ @@ -257,7 +274,7 @@ void ads_dump(ADS_STRUCT *ads, void *res) void (*handler)(const char *, struct berval **); } handlers[] = { {"objectGUID", dump_binary}, - {"objectSid", dump_binary}, + {"objectSid", dump_sid}, {NULL, NULL} }; @@ -547,12 +564,16 @@ BOOL ads_server_info(ADS_STRUCT *ads) *p = 0; + SAFE_FREE(ads->server_realm); + SAFE_FREE(ads->bind_path); + + ads->server_realm = strdup(p+2); + ads->bind_path = ads_build_dn(ads->server_realm); + /* in case the realm isn't configured in smb.conf */ if (!ads->realm || !ads->realm[0]) { SAFE_FREE(ads->realm); - SAFE_FREE(ads->bind_path); - ads->realm = strdup(p+2); - ads->bind_path = ads_build_dn(ads->realm); + ads->realm = strdup(ads->server_realm); } DEBUG(3,("got ldap server name %s@%s\n", @@ -561,4 +582,44 @@ BOOL ads_server_info(ADS_STRUCT *ads) return True; } + +/* + find the list of trusted domains +*/ +BOOL ads_trusted_domains(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, + int *num_trusts, char ***names, DOM_SID **sids) +{ + const char *attrs[] = {"flatName", "securityIdentifier", NULL}; + int rc; + void *res, *msg; + int count, i; + + *num_trusts = 0; + + rc = ads_search(ads, &res, "(objectcategory=trustedDomain)", attrs); + if (rc) return False; + + count = ads_count_replies(ads, res); + if (count == 0) { + ads_msgfree(ads, res); + return False; + } + + (*names) = talloc(mem_ctx, sizeof(char *) * count); + (*sids) = talloc(mem_ctx, sizeof(DOM_SID) * count); + if (! *names || ! *sids) return False; + + for (i=0, msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) { + (*names)[i] = ads_pull_string(ads, mem_ctx, msg, "flatName"); + ads_pull_sid(ads, msg, "securityIdentifier", &(*sids)[i]); + i++; + } + + ads_msgfree(ads, res); + + *num_trusts = i; + + return True; +} + #endif diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index dd948b5d4d..b3610b8fdb 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -53,9 +53,9 @@ static int sasl_interact(LDAP *ld,unsigned flags,void *defaults,void *in) this routine is much less fragile see RFC2078 for details */ -int ads_sasl_gssapi_bind(ADS_STRUCT *ads) +ADS_RETURN_CODE ads_sasl_gssapi_bind(ADS_STRUCT *ads) { - int rc, minor_status; + int minor_status; gss_name_t serv_name; gss_buffer_desc input_name; gss_ctx_id_t context_handle; @@ -69,15 +69,27 @@ int ads_sasl_gssapi_bind(ADS_STRUCT *ads) uint8 *p; uint32 max_msg_size; char *sname; + ADS_RETURN_CODE rc; + krb5_principal principal; + krb5_context ctx; + krb5_enctype enc_types[] = {ENCTYPE_DES_CBC_MD5, ENCTYPE_NULL}; + gss_OID_desc nt_principal = + {10, "\052\206\110\206\367\022\001\002\002\002"}; + + /* we need to fetch a service ticket as the ldap user in the + servers realm, regardless of our realm */ + asprintf(&sname, "ldap/%s@%s", ads->ldap_server_name, ads->server_realm); + krb5_init_context(&ctx); + krb5_set_default_tgs_ktypes(ctx, enc_types); + krb5_parse_name(ctx, sname, &principal); + free(sname); + krb5_free_context(ctx); - asprintf(&sname, "ldap@%s.%s", ads->ldap_server_name, ads->realm); - - input_name.value = sname; - input_name.length = strlen(input_name.value); - - rc = gss_import_name(&minor_status,&input_name,gss_nt_service_name, &serv_name); + input_name.value = &principal; + input_name.length = sizeof(principal); - free(sname); + rc.rc = gss_import_name(&minor_status,&input_name,&nt_principal, &serv_name); + rc.error_type = False; context_handle = GSS_C_NO_CONTEXT; @@ -103,12 +115,17 @@ int ads_sasl_gssapi_bind(ADS_STRUCT *ads) gss_release_buffer(&minor_status, &input_token); } - if (gss_rc && gss_rc != GSS_S_CONTINUE_NEEDED) goto failed; + if (gss_rc && gss_rc != GSS_S_CONTINUE_NEEDED) { + rc.minor_status = minor_status; + rc.rc = gss_rc; + rc.error_type = True; + goto failed; + } cred.bv_val = output_token.value; cred.bv_len = output_token.length; - rc = ldap_sasl_bind_s(ads->ld, NULL, "GSSAPI", &cred, NULL, NULL, + rc.rc = ldap_sasl_bind_s(ads->ld, NULL, "GSSAPI", &cred, NULL, NULL, &scred); if (output_token.value) { @@ -152,7 +169,7 @@ int ads_sasl_gssapi_bind(ADS_STRUCT *ads) output_token.length = strlen(ads->bind_path) + 8; - gss_rc = gss_wrap(&minor_status, context_handle,0,GSS_C_QOP_DEFAULT, + rc.rc = gss_wrap(&minor_status, context_handle,0,GSS_C_QOP_DEFAULT, &output_token, &conf_state, &input_token); @@ -161,22 +178,24 @@ int ads_sasl_gssapi_bind(ADS_STRUCT *ads) cred.bv_val = input_token.value; cred.bv_len = input_token.length; - rc = ldap_sasl_bind_s(ads->ld, NULL, "GSSAPI", &cred, NULL, NULL, + rc.rc = ldap_sasl_bind_s(ads->ld, NULL, "GSSAPI", &cred, NULL, NULL, &scred); gss_release_buffer(&minor_status, &input_token); - return rc; failed: - return gss_rc; + return rc; } -int ads_sasl_bind(ADS_STRUCT *ads) +ADS_RETURN_CODE ads_sasl_bind(ADS_STRUCT *ads) { #if USE_CYRUS_SASL - return ldap_sasl_interactive_bind_s(ads->ld, NULL, NULL, NULL, NULL, + ADS_RETURN_CODE rc; + rc.error_type = False; + rc.rc = ldap_sasl_interactive_bind_s(ads->ld, NULL, NULL, NULL, NULL, LDAP_SASL_QUIET, sasl_interact, NULL); + return rc; #else return ads_sasl_gssapi_bind(ads); #endif -- cgit From 105fe2a32eccc63f63ddf903278b80fb211f05bf Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 19 Dec 2001 09:58:52 +0000 Subject: we only have gss_ fns on a krb5 capable box (This used to be commit 344b786efe00f72ed81f0eeb4d422c655d866557) --- source3/libads/ads_struct.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index a7c8d1a681..83d423104e 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -157,8 +157,8 @@ void ads_destroy(ADS_STRUCT **ads) } } - -static void ads_display_status_helper(char *m, OM_uint32 code, int type) +#if HAVE_KRB5 +static void ads_display_status_helper(const char *m, uint32 code, int type) { int maj_stat, min_stat; gss_buffer_desc msg; @@ -177,9 +177,12 @@ static void ads_display_status_helper(char *m, OM_uint32 code, int type) break; } } +#endif -void ads_display_status(char * msg, int maj_stat,int min_stat) +void ads_display_status(const char *msg, int maj_stat,int min_stat) { +#if HAVE_KRB5 ads_display_status_helper(msg, maj_stat, GSS_C_GSS_CODE); ads_display_status_helper(msg, min_stat, GSS_C_MECH_CODE); +#endif } -- cgit From 1f31ace6cb771d7bf0b64091fba1d24c466ad4e5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 19 Dec 2001 12:21:12 +0000 Subject: much better ADS error handling system (This used to be commit 05a90a28843e0d69183a49a76617c5f32817df16) --- source3/libads/ads_struct.c | 34 +------ source3/libads/krb5_setpw.c | 36 +++---- source3/libads/ldap.c | 234 ++++++++++++++++++++++++++------------------ source3/libads/sasl.c | 54 ++++++---- 4 files changed, 196 insertions(+), 162 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index 83d423104e..013491eaed 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -22,6 +22,10 @@ #include "includes.h" +/* return a dn of the form "dc=AA,dc=BB,dc=CC" from a + realm of the form AA.BB.CC + caller must free +*/ char *ads_build_dn(const char *realm) { char *p, *r; @@ -156,33 +160,3 @@ void ads_destroy(ADS_STRUCT **ads) SAFE_FREE(*ads); } } - -#if HAVE_KRB5 -static void ads_display_status_helper(const char *m, uint32 code, int type) -{ - int maj_stat, min_stat; - gss_buffer_desc msg; - int msg_ctx; - - msg_ctx = 0; - while (1) { - maj_stat = gss_display_status(&min_stat, code, - type, GSS_C_NULL_OID, - &msg_ctx, &msg); - DEBUG(1, ("GSS-API error %s: %s\n", m, - (char *)msg.value)); - (void) gss_release_buffer(&min_stat, &msg); - - if (!msg_ctx) - break; - } -} -#endif - -void ads_display_status(const char *msg, int maj_stat,int min_stat) -{ -#if HAVE_KRB5 - ads_display_status_helper(msg, maj_stat, GSS_C_GSS_CODE); - ads_display_status_helper(msg, min_stat, GSS_C_MECH_CODE); -#endif -} diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 1c3b15d2a5..b46a579263 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -212,8 +212,8 @@ static krb5_error_code parse_setpw_reply(krb5_context context, return 0; } -NTSTATUS krb5_set_password(const char *kdc_host, const char *hostname, - const char *realm, const char *newpw) +ADS_STATUS krb5_set_password(const char *kdc_host, const char *hostname, + const char *realm, const char *newpw) { krb5_context context; krb5_auth_context auth_context = NULL; @@ -229,13 +229,13 @@ NTSTATUS krb5_set_password(const char *kdc_host, const char *hostname, ret = krb5_init_context(&context); if (ret) { DEBUG(1,("Failed to init krb5 context (%s)\n", error_message(ret))); - return NT_STATUS_UNSUCCESSFUL; + return ADS_ERROR_KRB5(ret); } ret = krb5_cc_default(context, &ccache); if (ret) { DEBUG(1,("Failed to get default creds (%s)\n", error_message(ret))); - return NT_STATUS_UNSUCCESSFUL; + return ADS_ERROR_KRB5(ret); } ZERO_STRUCT(creds); @@ -244,7 +244,7 @@ NTSTATUS krb5_set_password(const char *kdc_host, const char *hostname, ret = krb5_parse_name(context, princ_name, &creds.server); if (ret) { DEBUG(1,("Failed to parse kadmin/changepw (%s)\n", error_message(ret))); - return NT_STATUS_UNSUCCESSFUL; + return ADS_ERROR_KRB5(ret); } free(princ_name); @@ -252,7 +252,7 @@ NTSTATUS krb5_set_password(const char *kdc_host, const char *hostname, ret = krb5_parse_name(context, princ_name, &principal); if (ret) { DEBUG(1,("Failed to parse %s (%s)\n", princ_name, error_message(ret))); - return NT_STATUS_UNSUCCESSFUL; + return ADS_ERROR_KRB5(ret); } free(princ_name); @@ -263,27 +263,28 @@ NTSTATUS krb5_set_password(const char *kdc_host, const char *hostname, if (ret) { DEBUG(1,("Failed to get principal from ccache (%s)\n", error_message(ret))); - return NT_STATUS_UNSUCCESSFUL; + return ADS_ERROR_KRB5(ret); } ret = krb5_get_credentials(context, 0, ccache, &creds, &credsp); if (ret) { DEBUG(1,("krb5_get_credentials failed (%s)\n", error_message(ret))); - return NT_STATUS_UNSUCCESSFUL; + return ADS_ERROR_KRB5(ret); } ret = krb5_mk_req_extended(context, &auth_context, AP_OPTS_USE_SUBKEY, NULL, credsp, &ap_req); if (ret) { DEBUG(1,("krb5_mk_req_extended failed (%s)\n", error_message(ret))); - return NT_STATUS_UNSUCCESSFUL; + return ADS_ERROR_KRB5(ret); } sock = open_udp_socket(kdc_host, DEFAULT_KPASSWD_PORT); if (sock == -1) { + int rc = errno; DEBUG(1,("failed to open kpasswd socket to %s (%s)\n", kdc_host, strerror(errno))); - return NT_STATUS_UNSUCCESSFUL; + return ADS_ERROR_SYSTEM(rc); } addr_len = sizeof(remote_addr); @@ -301,19 +302,19 @@ NTSTATUS krb5_set_password(const char *kdc_host, const char *hostname, ret = krb5_auth_con_setaddrs(context, auth_context, &local_kaddr, NULL); if (ret) { DEBUG(1,("krb5_auth_con_setaddrs failed (%s)\n", error_message(ret))); - return NT_STATUS_UNSUCCESSFUL; + return ADS_ERROR_KRB5(ret); } ret = build_setpw_request(context, auth_context, &ap_req, hostname, realm, newpw, &chpw_req); if (ret) { DEBUG(1,("build_setpw_request failed (%s)\n", error_message(ret))); - return NT_STATUS_UNSUCCESSFUL; + return ADS_ERROR_KRB5(ret); } if (write(sock, chpw_req.data, chpw_req.length) != chpw_req.length) { DEBUG(1,("send of chpw failed (%s)\n", strerror(errno))); - return NT_STATUS_UNSUCCESSFUL; + return ADS_ERROR(LDAP_ENCODING_ERROR); } free(chpw_req.data); @@ -323,8 +324,7 @@ NTSTATUS krb5_set_password(const char *kdc_host, const char *hostname, ret = read(sock, chpw_rep.data, chpw_rep.length); if (ret < 0) { - DEBUG(1,("recv of chpw reply failed (%s)\n", strerror(errno))); - return NT_STATUS_UNSUCCESSFUL; + return ADS_ERROR_SYSTEM(errno); } close(sock); @@ -334,7 +334,7 @@ NTSTATUS krb5_set_password(const char *kdc_host, const char *hostname, if (ret) { DEBUG(1,("krb5_auth_con_setaddrs on reply failed (%s)\n", error_message(ret))); - return NT_STATUS_UNSUCCESSFUL; + return ADS_ERROR_KRB5(ret); } ret = parse_setpw_reply(context, auth_context, &chpw_rep); @@ -343,10 +343,10 @@ NTSTATUS krb5_set_password(const char *kdc_host, const char *hostname, if (ret) { DEBUG(1,("parse_setpw_reply failed (%s)\n", error_message(ret))); - return NT_STATUS_UNSUCCESSFUL; + return ADS_ERROR_KRB5(ret); } - return NT_STATUS_OK; + return ADS_SUCCESS; } #endif diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index b41a864ae2..3452614315 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -23,39 +23,83 @@ #ifdef HAVE_ADS -/* return a dn of the form "dc=AA,dc=BB,dc=CC" from a - realm of the form AA.BB.CC - caller must free +/* + build a ADS_STATUS structure +*/ +ADS_STATUS ads_build_error(enum ads_error_type etype, + int rc, int minor_status) +{ + ADS_STATUS ret; + ret.error_type = etype; + ret.rc = rc; + ret.minor_status = minor_status; + return ret; +} + +/* + do a rough conversion between ads error codes and NT status codes + we'll need to fill this in more */ +NTSTATUS ads_ntstatus(ADS_STATUS rc) +{ + if (ADS_ERR_OK(rc)) return NT_STATUS_OK; + return NT_STATUS_UNSUCCESSFUL; +} + /* return a string for an error from a ads routine */ -char *ads_errstr(int rc) +const char *ads_errstr(ADS_STATUS status) { - return ldap_err2string(rc); + gss_buffer_desc msg1, msg2; + uint32 minor; + int msg_ctx; + static char *ret; + + SAFE_FREE(ret); + msg_ctx = 0; + + switch (status.error_type) { + case ADS_ERROR_KRB5: + return error_message(status.rc); + case ADS_ERROR_LDAP: + return ldap_err2string(status.rc); + case ADS_ERROR_SYSTEM: + return strerror(status.rc); + case ADS_ERROR_GSS: + msg1.value = NULL; + msg2.value = NULL; + gss_display_status(&minor, status.rc, GSS_C_GSS_CODE, + GSS_C_NULL_OID, &msg_ctx, &msg1); + gss_display_status(&minor, status.minor_status, GSS_C_MECH_CODE, + GSS_C_NULL_OID, &msg_ctx, &msg2); + asprintf(&ret, "%s : %s", (char *)msg1.value, (char *)msg2.value); + gss_release_buffer(&minor, &msg1); + gss_release_buffer(&minor, &msg2); + return ret; + } + + return "Unknown ADS error type!?"; } /* connect to the LDAP server */ -ADS_RETURN_CODE ads_connect(ADS_STRUCT *ads) +ADS_STATUS ads_connect(ADS_STRUCT *ads) { int version = LDAP_VERSION3; - ADS_RETURN_CODE rc; - - rc.error_type = False; + ADS_STATUS status; ads->last_attempt = time(NULL); ads->ld = ldap_open(ads->ldap_server, ads->ldap_port); if (!ads->ld) { - rc.rc = LDAP_SERVER_DOWN; - return rc; + return ADS_ERROR_SYSTEM(errno) } - if (!ads_server_info(ads)) { + status = ads_server_info(ads); + if (!ADS_ERR_OK(status)) { DEBUG(1,("Failed to get ldap server info\n")); - rc.rc = LDAP_SERVER_DOWN; - return rc; + return status; } ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); @@ -64,33 +108,35 @@ ADS_RETURN_CODE ads_connect(ADS_STRUCT *ads) ads_kinit_password(ads); } - rc = ads_sasl_bind(ads); - return rc; + return ads_sasl_bind(ads); } /* do a search with a timeout */ -int ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, const char *exp, - const char **attrs, void **res) +ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, + const char *exp, + const char **attrs, void **res) { struct timeval timeout; + int rc; timeout.tv_sec = ADS_SEARCH_TIMEOUT; timeout.tv_usec = 0; *res = NULL; - return ldap_search_ext_s(ads->ld, - bind_path, scope, - exp, attrs, 0, NULL, NULL, - &timeout, LDAP_NO_LIMIT, (LDAPMessage **)res); + rc = ldap_search_ext_s(ads->ld, + bind_path, scope, + exp, attrs, 0, NULL, NULL, + &timeout, LDAP_NO_LIMIT, (LDAPMessage **)res); + return ADS_ERROR(rc); } /* do a general ADS search */ -int ads_search(ADS_STRUCT *ads, void **res, - const char *exp, - const char **attrs) +ADS_STATUS ads_search(ADS_STRUCT *ads, void **res, + const char *exp, + const char **attrs) { return ads_do_search(ads, ads->bind_path, LDAP_SCOPE_SUBTREE, exp, attrs, res); @@ -99,9 +145,9 @@ int ads_search(ADS_STRUCT *ads, void **res, /* do a search on a specific DistinguishedName */ -int ads_search_dn(ADS_STRUCT *ads, void **res, - const char *dn, - const char **attrs) +ADS_STATUS ads_search_dn(ADS_STRUCT *ads, void **res, + const char *dn, + const char **attrs) { return ads_do_search(ads, dn, LDAP_SCOPE_BASE, "(objectclass=*)", attrs, res); } @@ -118,24 +164,24 @@ void ads_msgfree(ADS_STRUCT *ads, void *msg) /* find a machine account given a hostname */ -int ads_find_machine_acct(ADS_STRUCT *ads, void **res, const char *host) +ADS_STATUS ads_find_machine_acct(ADS_STRUCT *ads, void **res, const char *host) { - int ret; + ADS_STATUS status; char *exp; /* the easiest way to find a machine account anywhere in the tree is to look for hostname$ */ asprintf(&exp, "(samAccountName=%s$)", host); - ret = ads_search(ads, res, exp, NULL); + status = ads_search(ads, res, exp, NULL); free(exp); - return ret; + return status; } /* a convenient routine for adding a generic LDAP record */ -int ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ...) +ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ...) { int i; va_list ap; @@ -179,15 +225,16 @@ int ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ...) } free(mods); - return ret; + return ADS_ERROR(ret); } /* add a machine account to the ADS server */ -static int ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, const char *org_unit) +static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, + const char *org_unit) { - int ret; + ADS_STATUS ret; char *host_spn, *host_upn, *new_dn, *samAccountName, *controlstr; asprintf(&host_spn, "HOST/%s", hostname); @@ -317,9 +364,9 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) join a machine to a realm, creating the machine account and setting the machine password */ -int ads_join_realm(ADS_STRUCT *ads, const char *hostname, const char *org_unit) +ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *hostname, const char *org_unit) { - int rc; + ADS_STATUS status; LDAPMessage *res; char *host; @@ -327,80 +374,78 @@ int ads_join_realm(ADS_STRUCT *ads, const char *hostname, const char *org_unit) host = strdup(hostname); strlower(host); - rc = ads_find_machine_acct(ads, (void **)&res, host); - if (rc == LDAP_SUCCESS && ads_count_replies(ads, res) == 1) { + status = ads_find_machine_acct(ads, (void **)&res, host); + if (ADS_ERR_OK(status) && ads_count_replies(ads, res) == 1) { DEBUG(0, ("Host account for %s already exists\n", host)); - return LDAP_SUCCESS; + return ADS_SUCCESS; } - rc = ads_add_machine_acct(ads, host, org_unit); - if (rc != LDAP_SUCCESS) { - DEBUG(0, ("ads_add_machine_acct: %s\n", ads_errstr(rc))); - return rc; + status = ads_add_machine_acct(ads, host, org_unit); + if (!ADS_ERR_OK(status)) { + DEBUG(0, ("ads_add_machine_acct: %s\n", ads_errstr(status))); + return status; } - rc = ads_find_machine_acct(ads, (void **)&res, host); - if (rc != LDAP_SUCCESS || ads_count_replies(ads, res) != 1) { + status = ads_find_machine_acct(ads, (void **)&res, host); + if (!ADS_ERR_OK(status)) { DEBUG(0, ("Host account test failed\n")); - /* hmmm, we need NTSTATUS */ - return -1; + return status; } free(host); - return LDAP_SUCCESS; + return status; } /* delete a machine from the realm */ -int ads_leave_realm(ADS_STRUCT *ads, const char *hostname) +ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) { - int rc; + ADS_STATUS status; void *res; char *hostnameDN, *host; + int rc; /* hostname must be lowercase */ host = strdup(hostname); strlower(host); - rc = ads_find_machine_acct(ads, &res, host); - if (rc != LDAP_SUCCESS || ads_count_replies(ads, res) != 1) { + status = ads_find_machine_acct(ads, &res, host); + if (!ADS_ERR_OK(status)) { DEBUG(0, ("Host account for %s does not exist.\n", host)); - return -1; + return status; } hostnameDN = ldap_get_dn(ads->ld, (LDAPMessage *)res); rc = ldap_delete_s(ads->ld, hostnameDN); ldap_memfree(hostnameDN); if (rc != LDAP_SUCCESS) { - DEBUG(0, ("ldap_delete_s: %s\n", ads_errstr(rc))); - return rc; + return ADS_ERROR(rc); } - rc = ads_find_machine_acct(ads, &res, host); - if (rc == LDAP_SUCCESS && ads_count_replies(ads, res) == 1 ) { - DEBUG(0, ("Failed to remove host account.\n")); - /*hmmm, we need NTSTATUS */ - return -1; + status = ads_find_machine_acct(ads, &res, host); + if (ADS_ERR_OK(status) && ads_count_replies(ads, res) == 1) { + DEBUG(0, ("Failed to remove host account.\n")); + return status; } free(host); - return LDAP_SUCCESS; + return status; } -NTSTATUS ads_set_machine_password(ADS_STRUCT *ads, - const char *hostname, - const char *password) +ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads, + const char *hostname, + const char *password) { - NTSTATUS ret; + ADS_STATUS status; char *host = strdup(hostname); strlower(host); - ret = krb5_set_password(ads->kdc_server, host, ads->realm, password); + status = krb5_set_password(ads->kdc_server, host, ads->realm, password); free(host); - return ret; + return status; } /* @@ -510,18 +555,22 @@ int ads_pull_sids(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, /* find the update serial number - this is the core of the ldap cache */ -BOOL ads_USN(ADS_STRUCT *ads, uint32 *usn) +ADS_STATUS ads_USN(ADS_STRUCT *ads, uint32 *usn) { const char *attrs[] = {"highestCommittedUSN", NULL}; - int rc; + ADS_STATUS status; void *res; - BOOL ret; - rc = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); - if (rc || ads_count_replies(ads, res) != 1) return False; - ret = ads_pull_uint32(ads, res, "highestCommittedUSN", usn); + status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); + if (!ADS_ERR_OK(status)) return status; + + if (ads_count_replies(ads, res) != 1) { + return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); + } + + ads_pull_uint32(ads, res, "highestCommittedUSN", usn); ads_msgfree(ads, res); - return ret; + return ADS_SUCCESS; } @@ -529,26 +578,25 @@ BOOL ads_USN(ADS_STRUCT *ads, uint32 *usn) The ldapServiceName field on w2k looks like this: vnet3.home.samba.org:win2000-vnet3$@VNET3.HOME.SAMBA.ORG */ -BOOL ads_server_info(ADS_STRUCT *ads) +ADS_STATUS ads_server_info(ADS_STRUCT *ads) { const char *attrs[] = {"ldapServiceName", NULL}; - int rc; + ADS_STATUS status; void *res; char **values; char *p; - rc = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); - if (rc || ads_count_replies(ads, res) != 1) return False; + status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); + if (!ADS_ERR_OK(status)) return status; values = ldap_get_values(ads->ld, res, "ldapServiceName"); - - if (!values || !values[0]) return False; + if (!values || !values[0]) return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); p = strchr(values[0], ':'); if (!p) { ldap_value_free(values); ldap_msgfree(res); - return False; + return ADS_ERROR(LDAP_DECODING_ERROR); } SAFE_FREE(ads->ldap_server_name); @@ -559,7 +607,7 @@ BOOL ads_server_info(ADS_STRUCT *ads) ldap_value_free(values); ldap_msgfree(res); SAFE_FREE(ads->ldap_server_name); - return False; + return ADS_ERROR(LDAP_DECODING_ERROR); } *p = 0; @@ -579,35 +627,35 @@ BOOL ads_server_info(ADS_STRUCT *ads) DEBUG(3,("got ldap server name %s@%s\n", ads->ldap_server_name, ads->realm)); - return True; + return ADS_SUCCESS; } /* find the list of trusted domains */ -BOOL ads_trusted_domains(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, - int *num_trusts, char ***names, DOM_SID **sids) +ADS_STATUS ads_trusted_domains(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, + int *num_trusts, char ***names, DOM_SID **sids) { const char *attrs[] = {"flatName", "securityIdentifier", NULL}; - int rc; + ADS_STATUS status; void *res, *msg; int count, i; *num_trusts = 0; - rc = ads_search(ads, &res, "(objectcategory=trustedDomain)", attrs); - if (rc) return False; + status = ads_search(ads, &res, "(objectcategory=trustedDomain)", attrs); + if (!ADS_ERR_OK(status)) return status; count = ads_count_replies(ads, res); if (count == 0) { ads_msgfree(ads, res); - return False; + return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); } (*names) = talloc(mem_ctx, sizeof(char *) * count); (*sids) = talloc(mem_ctx, sizeof(DOM_SID) * count); - if (! *names || ! *sids) return False; + if (! *names || ! *sids) return ADS_ERROR(LDAP_NO_MEMORY); for (i=0, msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) { (*names)[i] = ads_pull_string(ads, mem_ctx, msg, "flatName"); @@ -619,7 +667,7 @@ BOOL ads_trusted_domains(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, *num_trusts = i; - return True; + return ADS_SUCCESS; } #endif diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index b3610b8fdb..48873252f0 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -53,7 +53,7 @@ static int sasl_interact(LDAP *ld,unsigned flags,void *defaults,void *in) this routine is much less fragile see RFC2078 for details */ -ADS_RETURN_CODE ads_sasl_gssapi_bind(ADS_STRUCT *ads) +ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) { int minor_status; gss_name_t serv_name; @@ -65,11 +65,11 @@ ADS_RETURN_CODE ads_sasl_gssapi_bind(ADS_STRUCT *ads) struct berval cred; struct berval *scred; int i=0; - int gss_rc; + int gss_rc, rc; uint8 *p; uint32 max_msg_size; char *sname; - ADS_RETURN_CODE rc; + ADS_STATUS status; krb5_principal principal; krb5_context ctx; krb5_enctype enc_types[] = {ENCTYPE_DES_CBC_MD5, ENCTYPE_NULL}; @@ -88,8 +88,10 @@ ADS_RETURN_CODE ads_sasl_gssapi_bind(ADS_STRUCT *ads) input_name.value = &principal; input_name.length = sizeof(principal); - rc.rc = gss_import_name(&minor_status,&input_name,&nt_principal, &serv_name); - rc.error_type = False; + gss_rc = gss_import_name(&minor_status,&input_name,&nt_principal, &serv_name); + if (gss_rc) { + return ADS_ERROR_GSS(gss_rc, minor_status); + } context_handle = GSS_C_NO_CONTEXT; @@ -116,17 +118,19 @@ ADS_RETURN_CODE ads_sasl_gssapi_bind(ADS_STRUCT *ads) } if (gss_rc && gss_rc != GSS_S_CONTINUE_NEEDED) { - rc.minor_status = minor_status; - rc.rc = gss_rc; - rc.error_type = True; - goto failed; + status = ADS_ERROR_GSS(gss_rc, minor_status); + goto failed; } cred.bv_val = output_token.value; cred.bv_len = output_token.length; - rc.rc = ldap_sasl_bind_s(ads->ld, NULL, "GSSAPI", &cred, NULL, NULL, + rc = ldap_sasl_bind_s(ads->ld, NULL, "GSSAPI", &cred, NULL, NULL, &scred); + if (rc != LDAP_SASL_BIND_IN_PROGRESS) { + status = ADS_ERROR(rc); + goto failed; + } if (output_token.value) { gss_release_buffer(&minor_status, &output_token); @@ -140,13 +144,17 @@ ADS_RETURN_CODE ads_sasl_gssapi_bind(ADS_STRUCT *ads) input_token.length = 0; } - if (gss_rc != GSS_S_CONTINUE_NEEDED) break; + if (gss_rc == 0) break; } gss_release_name(&minor_status, &serv_name); gss_rc = gss_unwrap(&minor_status,context_handle,&input_token,&output_token, &conf_state,NULL); + if (gss_rc) { + status = ADS_ERROR_GSS(gss_rc, minor_status); + goto failed; + } gss_release_buffer(&minor_status, &input_token); @@ -169,33 +177,37 @@ ADS_RETURN_CODE ads_sasl_gssapi_bind(ADS_STRUCT *ads) output_token.length = strlen(ads->bind_path) + 8; - rc.rc = gss_wrap(&minor_status, context_handle,0,GSS_C_QOP_DEFAULT, + gss_rc = gss_wrap(&minor_status, context_handle,0,GSS_C_QOP_DEFAULT, &output_token, &conf_state, &input_token); + if (gss_rc) { + status = ADS_ERROR_GSS(gss_rc, minor_status); + goto failed; + } free(output_token.value); cred.bv_val = input_token.value; cred.bv_len = input_token.length; - rc.rc = ldap_sasl_bind_s(ads->ld, NULL, "GSSAPI", &cred, NULL, NULL, + rc = ldap_sasl_bind_s(ads->ld, NULL, "GSSAPI", &cred, NULL, NULL, &scred); + status = ADS_ERROR(rc); gss_release_buffer(&minor_status, &input_token); failed: - return rc; + return status; } -ADS_RETURN_CODE ads_sasl_bind(ADS_STRUCT *ads) +ADS_STATUS ads_sasl_bind(ADS_STRUCT *ads) { #if USE_CYRUS_SASL - ADS_RETURN_CODE rc; - rc.error_type = False; - rc.rc = ldap_sasl_interactive_bind_s(ads->ld, NULL, NULL, NULL, NULL, - LDAP_SASL_QUIET, - sasl_interact, NULL); - return rc; + int rc; + rc = ldap_sasl_interactive_bind_s(ads->ld, NULL, NULL, NULL, NULL, + LDAP_SASL_QUIET, + sasl_interact, NULL); + return ADS_ERROR(rc); #else return ads_sasl_gssapi_bind(ads); #endif -- cgit From 6c7e9dfb293f1243d9d8d8a2ac50ef12d738198e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 20 Dec 2001 03:54:52 +0000 Subject: net ads password and net ads chostpass commands from Remus Koos (This used to be commit 412e79c448bf02e3097b5c14a36fe0172d8d2895) --- source3/libads/kerberos.c | 13 ++-- source3/libads/krb5_setpw.c | 145 +++++++++++++++++++++++++++++++++++++++----- source3/libads/ldap.c | 12 +++- 3 files changed, 147 insertions(+), 23 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 8378442885..aba22e023b 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -3,6 +3,8 @@ Version 3.0 kerberos utility library Copyright (C) Andrew Tridgell 2001 + Copyright (C) Remus Koos 2001 + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -27,8 +29,7 @@ simulate a kinit, putting the tgt in the default cache location remus@snapserver.com */ -int kerberos_kinit_password(const char *principal, const char *password, - time_t real_time) +int kerberos_kinit_password(const char *principal, const char *password) { krb5_context ctx; krb5_error_code code = 0; @@ -44,10 +45,6 @@ int kerberos_kinit_password(const char *principal, const char *password, if ((code = krb5_init_context(&ctx))) return code; - if (real_time) { - krb5_set_real_time(ctx, real_time, 0); - } - if ((code = krb5_cc_default(ctx, &cc))) { krb5_free_context(ctx); return code; @@ -58,7 +55,7 @@ int kerberos_kinit_password(const char *principal, const char *password, return code; } - if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, password, NULL, + if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, (char*)password, NULL, NULL, 0, NULL, NULL))) { krb5_free_principal(ctx, me); krb5_free_context(ctx); @@ -105,7 +102,7 @@ int ads_kinit_password(ADS_STRUCT *ads) asprintf(&ads->user_name, "HOST/%s", global_myname); } asprintf(&s, "%s@%s", ads->user_name, ads->realm); - ret = kerberos_kinit_password(s, ads->password, 0); + ret = kerberos_kinit_password(s, ads->password); if (ret) { DEBUG(0,("kerberos_kinit_password %s failed: %s\n", diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index b46a579263..e15c22091d 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -3,6 +3,7 @@ Version 3.0 krb5 set password implementation Copyright (C) Andrew Tridgell 2001 + Copyright (C) Remus Koos 2001 (remuskoos@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -32,12 +33,36 @@ /* This implements the Kerb password change protocol as specifed in * kerb-chg-password-02.txt */ -static DATA_BLOB encode_krb5_setpw(const char *hostname, - const char *realm, const char *password) +static DATA_BLOB encode_krb5_setpw(const char *principal, const char *password) { + char* princ_part1 = NULL; + char* princ_part2 = NULL; + char* realm = NULL; + char* c; + char* princ; + ASN1_DATA req; DATA_BLOB ret; + + princ = strdup(principal); + + if ((c = strchr(princ, '/')) == NULL) { + c = princ; + } else { + *c = '\0'; + c++; + princ_part1 = princ; + } + + princ_part2 = c; + + if ((c = strchr(c, '@')) != NULL) { + *c = '\0'; + c++; + realm = c; + } + memset(&req, 0, sizeof(req)); asn1_push_tag(&req, ASN1_SEQUENCE(0)); @@ -54,8 +79,11 @@ static DATA_BLOB encode_krb5_setpw(const char *hostname, asn1_push_tag(&req, ASN1_CONTEXT(1)); asn1_push_tag(&req, ASN1_SEQUENCE(0)); - asn1_write_GeneralString(&req, "HOST"); - asn1_write_GeneralString(&req, hostname); + + if (princ_part1) + asn1_write_GeneralString(&req, princ_part1); + + asn1_write_GeneralString(&req, princ_part2); asn1_pop_tag(&req); asn1_pop_tag(&req); asn1_pop_tag(&req); @@ -69,14 +97,15 @@ static DATA_BLOB encode_krb5_setpw(const char *hostname, ret = data_blob(req.data, req.length); asn1_free(&req); + free(princ); + return ret; } static krb5_error_code build_setpw_request(krb5_context context, krb5_auth_context auth_context, krb5_data *ap_req, - const char *hostname, - const char *realm, + const char *princ, const char *passwd, krb5_data *packet) { @@ -95,13 +124,16 @@ static krb5_error_code build_setpw_request(krb5_context context, return ret; } - setpw = encode_krb5_setpw(hostname, realm, passwd); + setpw = encode_krb5_setpw(princ, passwd); encoded_setpw.data = setpw.data; encoded_setpw.length = setpw.length; ret = krb5_mk_priv(context, auth_context, &encoded_setpw, &cipherpw, &replay); + + data_blob_free(&setpw); /*from 'encode_krb5_setpw(...)' */ + if (ret) { DEBUG(1,("krb5_mk_priv failed (%s)\n", error_message(ret))); return ret; @@ -118,6 +150,8 @@ static krb5_error_code build_setpw_request(krb5_context context, packet->length = PTR_DIFF(p,packet->data); RSSVAL(packet->data, 0, packet->length); + free(cipherpw.data); /* from 'krb5_mk_priv(...)' */ + return 0; } @@ -196,6 +230,7 @@ static krb5_error_code parse_setpw_reply(krb5_context context, } if (clearresult.length < 2) { + free(clearresult.data); ret = KRB5KRB_AP_ERR_MODIFIED; return KRB5KRB_AP_ERR_MODIFIED; } @@ -204,21 +239,23 @@ static krb5_error_code parse_setpw_reply(krb5_context context, res_code = RSVAL(p, 0); + free(clearresult.data); + if ((res_code < KRB5_KPASSWD_SUCCESS) || - (res_code > KRB5_KPASSWD_ACCESSDENIED)) { + (res_code >= KRB5_KPASSWD_ACCESSDENIED)) { return KRB5KRB_AP_ERR_MODIFIED; } return 0; } -ADS_STATUS krb5_set_password(const char *kdc_host, const char *hostname, - const char *realm, const char *newpw) +ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char *newpw) { krb5_context context; krb5_auth_context auth_context = NULL; krb5_principal principal; char *princ_name; + char *realm; krb5_creds creds, *credsp; krb5_ccache ccache; krb5_data ap_req, chpw_req, chpw_rep; @@ -234,33 +271,40 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *hostname, ret = krb5_cc_default(context, &ccache); if (ret) { + krb5_free_context(context); DEBUG(1,("Failed to get default creds (%s)\n", error_message(ret))); return ADS_ERROR_KRB5(ret); } ZERO_STRUCT(creds); + realm = strchr(princ, '@'); + realm++; + asprintf(&princ_name, "kadmin/changepw@%s", realm); ret = krb5_parse_name(context, princ_name, &creds.server); if (ret) { + krb5_free_context(context); DEBUG(1,("Failed to parse kadmin/changepw (%s)\n", error_message(ret))); return ADS_ERROR_KRB5(ret); } free(princ_name); - asprintf(&princ_name, "HOST/%s@%s", hostname, realm); - ret = krb5_parse_name(context, princ_name, &principal); + /* parse the principal we got as a function argument */ + ret = krb5_parse_name(context, princ, &principal); if (ret) { + krb5_free_context(context); DEBUG(1,("Failed to parse %s (%s)\n", princ_name, error_message(ret))); return ADS_ERROR_KRB5(ret); } - free(princ_name); krb5_princ_set_realm(context, creds.server, krb5_princ_realm(context, principal)); ret = krb5_cc_get_principal(context, ccache, &creds.client); if (ret) { + krb5_free_principal(context, principal); + krb5_free_context(context); DEBUG(1,("Failed to get principal from ccache (%s)\n", error_message(ret))); return ADS_ERROR_KRB5(ret); @@ -268,13 +312,21 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *hostname, ret = krb5_get_credentials(context, 0, ccache, &creds, &credsp); if (ret) { + krb5_free_principal(context, creds.client); + krb5_free_principal(context, principal); + krb5_free_context(context); DEBUG(1,("krb5_get_credentials failed (%s)\n", error_message(ret))); return ADS_ERROR_KRB5(ret); } + //we might have to call krb5_free_creds(...) from now on ... ret = krb5_mk_req_extended(context, &auth_context, AP_OPTS_USE_SUBKEY, NULL, credsp, &ap_req); if (ret) { + krb5_free_creds(context, credsp); + krb5_free_principal(context, creds.client); + krb5_free_principal(context, principal); + krb5_free_context(context); DEBUG(1,("krb5_mk_req_extended failed (%s)\n", error_message(ret))); return ADS_ERROR_KRB5(ret); } @@ -282,6 +334,11 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *hostname, sock = open_udp_socket(kdc_host, DEFAULT_KPASSWD_PORT); if (sock == -1) { int rc = errno; + free(ap_req.data); + krb5_free_creds(context, credsp); + krb5_free_principal(context, creds.client); + krb5_free_principal(context, principal); + krb5_free_context(context); DEBUG(1,("failed to open kpasswd socket to %s (%s)\n", kdc_host, strerror(errno))); return ADS_ERROR_SYSTEM(rc); @@ -301,18 +358,37 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *hostname, ret = krb5_auth_con_setaddrs(context, auth_context, &local_kaddr, NULL); if (ret) { + close(sock); + free(ap_req.data); + krb5_free_creds(context, credsp); + krb5_free_principal(context, creds.client); + krb5_free_principal(context, principal); + krb5_free_context(context); DEBUG(1,("krb5_auth_con_setaddrs failed (%s)\n", error_message(ret))); return ADS_ERROR_KRB5(ret); } ret = build_setpw_request(context, auth_context, &ap_req, - hostname, realm, newpw, &chpw_req); + princ, newpw, &chpw_req); if (ret) { + close(sock); + free(ap_req.data); + krb5_free_creds(context, credsp); + krb5_free_principal(context, creds.client); + krb5_free_principal(context, principal); + krb5_free_context(context); DEBUG(1,("build_setpw_request failed (%s)\n", error_message(ret))); return ADS_ERROR_KRB5(ret); } if (write(sock, chpw_req.data, chpw_req.length) != chpw_req.length) { + close(sock); + free(chpw_req.data); + free(ap_req.data); + krb5_free_creds(context, credsp); + krb5_free_principal(context, creds.client); + krb5_free_principal(context, principal); + krb5_free_context(context); DEBUG(1,("send of chpw failed (%s)\n", strerror(errno))); return ADS_ERROR(LDAP_ENCODING_ERROR); } @@ -324,6 +400,14 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *hostname, ret = read(sock, chpw_rep.data, chpw_rep.length); if (ret < 0) { + close(sock); + free(chpw_rep.data); + free(ap_req.data); + krb5_free_creds(context, credsp); + krb5_free_principal(context, creds.client); + krb5_free_principal(context, principal); + krb5_free_context(context); + DEBUG(1,("recv of chpw reply failed (%s)\n", strerror(errno))); return ADS_ERROR_SYSTEM(errno); } @@ -332,6 +416,12 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *hostname, ret = krb5_auth_con_setaddrs(context, auth_context, NULL,&remote_kaddr); if (ret) { + free(chpw_rep.data); + free(ap_req.data); + krb5_free_creds(context, credsp); + krb5_free_principal(context, creds.client); + krb5_free_principal(context, principal); + krb5_free_context(context); DEBUG(1,("krb5_auth_con_setaddrs on reply failed (%s)\n", error_message(ret))); return ADS_ERROR_KRB5(ret); @@ -341,12 +431,39 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *hostname, free(chpw_rep.data); if (ret) { + free(ap_req.data); + krb5_free_creds(context, credsp); + krb5_free_principal(context, creds.client); + krb5_free_principal(context, principal); + krb5_free_context(context); DEBUG(1,("parse_setpw_reply failed (%s)\n", error_message(ret))); return ADS_ERROR_KRB5(ret); } + free(ap_req.data); + krb5_free_creds(context, credsp); + krb5_free_principal(context, creds.client); + krb5_free_principal(context, principal); + krb5_free_context(context); + return ADS_SUCCESS; } + +ADS_STATUS kerberos_set_password(const char *kpasswd_server, + const char *auth_principal, const char *auth_password, + const char *target_principal, const char *new_password) +{ + int ret; + + if ((ret = kerberos_kinit_password(auth_principal, auth_password))) { + DEBUG(1,("Failed kinit for principal %s (%s)\n", auth_principal, error_message(ret))); + return ADS_ERROR_KRB5(ret); + } + + return krb5_set_password(kpasswd_server, target_principal, new_password); +} + + #endif diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 3452614315..d2b9f74c4d 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -3,6 +3,8 @@ Version 3.0 ads (active directory) utility library Copyright (C) Andrew Tridgell 2001 + Copyright (C) Remus Koos 2001 + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -442,9 +444,17 @@ ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads, { ADS_STATUS status; char *host = strdup(hostname); + char *principal; + strlower(host); - status = krb5_set_password(ads->kdc_server, host, ads->realm, password); + + asprintf(&principal, "%s@%s", host, ads->realm); + + status = krb5_set_password(ads->kdc_server, principal, password); + free(host); + free(principal); + return status; } -- cgit From db54a8c04159fbce4d3d6427725634025ebb9286 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 20 Dec 2001 07:46:24 +0000 Subject: forgot to commit this file from remus (This used to be commit 7984ae0121ba327309ca5c52674e03fc1ad7e923) --- source3/libads/util.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 source3/libads/util.c (limited to 'source3/libads') diff --git a/source3/libads/util.c b/source3/libads/util.c new file mode 100644 index 0000000000..8f22adb7af --- /dev/null +++ b/source3/libads/util.c @@ -0,0 +1,59 @@ +/* + Unix SMB/Netbios implementation. + Version 3.0 + krb5 set password implementation + Copyright (C) Remus Koos 2001 (remuskoos@yahoo.com) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +#ifdef HAVE_KRB5 + +ADS_STATUS ads_change_trust_account_password(ADS_STRUCT *ads, char *host_principal) +{ + char *tmp_password; + char *password; + char *new_password; + char *service_principal; + ADS_STATUS ret; + + if ((password = secrets_fetch_machine_password()) == NULL) { + DEBUG(1,("Failed to retrieve password for principal %s\n", host_principal)); + return ADS_ERROR_SYSTEM(ENOENT); + } + + tmp_password = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH); + new_password = strdup(tmp_password); + asprintf(&service_principal, "HOST/%s", host_principal); + + ret = kerberos_set_password(ads->kdc_server, host_principal, password, + service_principal, new_password); + + if (!secrets_store_machine_password(new_password)) { + DEBUG(1,("Failed to save machine password\n")); + return ADS_ERROR_SYSTEM(EACCES); + } + + SAFE_FREE(service_principal); + SAFE_FREE(new_password); + + return ret; +} + + + +#endif -- cgit From 401c7495ea0286a46c97a18273419f122d1168a7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 20 Dec 2001 23:35:14 +0000 Subject: added ads_domain_sid() function (This used to be commit ff002a458afa6ca378f0c6d2ec9fb74233c839a7) --- source3/libads/ldap.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index d2b9f74c4d..8966ceb32a 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -680,4 +680,22 @@ ADS_STATUS ads_trusted_domains(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, return ADS_SUCCESS; } +/* find the domain sid for our domain */ +ADS_STATUS ads_domain_sid(ADS_STRUCT *ads, DOM_SID *sid) +{ + const char *attrs[] = {"objectSid", NULL}; + void *res; + ADS_STATUS rc; + + rc = ads_do_search(ads, ads->bind_path, LDAP_SCOPE_BASE, "(objectclass=*)", + attrs, &res); + if (!ADS_ERR_OK(rc)) return rc; + if (!ads_pull_sid(ads, res, "objectSid", sid)) { + return ADS_ERROR_SYSTEM(ENOENT); + } + ads_msgfree(ads, res); + + return ADS_SUCCESS; +} + #endif -- cgit From 34037e2479981073c8289fe51868b29096cc5808 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 30 Dec 2001 05:59:43 +0000 Subject: Make Samba compile on RH 6.2 again. We now include the libber.h file if required, but currently we just don't use ldap. (I'll chase this up). In the meantime, I've moved the ads_status code about, its now in its own file, and has a couple of #ifdefs to allow smbd to link - becouse the lack of LDAP caused HAVE_ADS to be undefined. (I hope its not too ugly). Andrew Bartlett (This used to be commit 14407c87e2dcccae1784290e3eb7a2d611516aff) --- source3/libads/ads_status.c | 91 +++++++++++++++++++++++++++++++++++++++++++++ source3/libads/ldap.c | 59 ----------------------------- 2 files changed, 91 insertions(+), 59 deletions(-) create mode 100644 source3/libads/ads_status.c (limited to 'source3/libads') diff --git a/source3/libads/ads_status.c b/source3/libads/ads_status.c new file mode 100644 index 0000000000..6dac335cc4 --- /dev/null +++ b/source3/libads/ads_status.c @@ -0,0 +1,91 @@ +/* + Unix SMB/Netbios implementation. + Version 3.0 + ads (active directory) utility library + Copyright (C) Andrew Tridgell 2001 + Copyright (C) Remus Koos 2001 + Copyright (C) Andrew Bartlett 2001 + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +/* + build a ADS_STATUS structure +*/ +ADS_STATUS ads_build_error(enum ads_error_type etype, + int rc, int minor_status) +{ + ADS_STATUS ret; + ret.error_type = etype; + ret.rc = rc; + ret.minor_status = minor_status; + return ret; +} + +/* + do a rough conversion between ads error codes and NT status codes + we'll need to fill this in more +*/ +NTSTATUS ads_ntstatus(ADS_STATUS rc) +{ + if (ADS_ERR_OK(rc)) return NT_STATUS_OK; + return NT_STATUS_UNSUCCESSFUL; +} + +/* + return a string for an error from a ads routine +*/ +const char *ads_errstr(ADS_STATUS status) +{ + gss_buffer_desc msg1, msg2; + uint32 minor; + int msg_ctx; + static char *ret; + + SAFE_FREE(ret); + msg_ctx = 0; + + switch (status.error_type) { + case ADS_ERROR_SYSTEM: + return strerror(status.rc); +#ifdef HAVE_LDAP + case ADS_ERROR_LDAP: + return ldap_err2string(status.rc); +#endif +#ifdef HAVE_KRB5 + case ADS_ERROR_KRB5: + return error_message(status.rc); + case ADS_ERROR_GSS: + msg1.value = NULL; + msg2.value = NULL; + gss_display_status(&minor, status.rc, GSS_C_GSS_CODE, + GSS_C_NULL_OID, &msg_ctx, &msg1); + gss_display_status(&minor, status.minor_status, GSS_C_MECH_CODE, + GSS_C_NULL_OID, &msg_ctx, &msg2); + asprintf(&ret, "%s : %s", (char *)msg1.value, (char *)msg2.value); + gss_release_buffer(&minor, &msg1); + gss_release_buffer(&minor, &msg2); + return ret; +#endif + default: + return "Unknown ADS error type!? (not compiled in?)"; + } + +} + + diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 8966ceb32a..5503b6e353 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -25,65 +25,6 @@ #ifdef HAVE_ADS -/* - build a ADS_STATUS structure -*/ -ADS_STATUS ads_build_error(enum ads_error_type etype, - int rc, int minor_status) -{ - ADS_STATUS ret; - ret.error_type = etype; - ret.rc = rc; - ret.minor_status = minor_status; - return ret; -} - -/* - do a rough conversion between ads error codes and NT status codes - we'll need to fill this in more -*/ -NTSTATUS ads_ntstatus(ADS_STATUS rc) -{ - if (ADS_ERR_OK(rc)) return NT_STATUS_OK; - return NT_STATUS_UNSUCCESSFUL; -} - -/* - return a string for an error from a ads routine -*/ -const char *ads_errstr(ADS_STATUS status) -{ - gss_buffer_desc msg1, msg2; - uint32 minor; - int msg_ctx; - static char *ret; - - SAFE_FREE(ret); - msg_ctx = 0; - - switch (status.error_type) { - case ADS_ERROR_KRB5: - return error_message(status.rc); - case ADS_ERROR_LDAP: - return ldap_err2string(status.rc); - case ADS_ERROR_SYSTEM: - return strerror(status.rc); - case ADS_ERROR_GSS: - msg1.value = NULL; - msg2.value = NULL; - gss_display_status(&minor, status.rc, GSS_C_GSS_CODE, - GSS_C_NULL_OID, &msg_ctx, &msg1); - gss_display_status(&minor, status.minor_status, GSS_C_MECH_CODE, - GSS_C_NULL_OID, &msg_ctx, &msg2); - asprintf(&ret, "%s : %s", (char *)msg1.value, (char *)msg2.value); - gss_release_buffer(&minor, &msg1); - gss_release_buffer(&minor, &msg2); - return ret; - } - - return "Unknown ADS error type!?"; -} - /* connect to the LDAP server */ -- cgit From 436595a3865e1e1d70847f238281a542952ce752 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 30 Dec 2001 06:20:23 +0000 Subject: Fix the compile on systems without a full kerberos kit. Andrew Bartlett (This used to be commit 33ae29028bffccf5a9cdd8d44b08c27b9d8fd982) --- source3/libads/ads_status.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_status.c b/source3/libads/ads_status.c index 6dac335cc4..51be9c806a 100644 --- a/source3/libads/ads_status.c +++ b/source3/libads/ads_status.c @@ -52,7 +52,6 @@ NTSTATUS ads_ntstatus(ADS_STATUS rc) */ const char *ads_errstr(ADS_STATUS status) { - gss_buffer_desc msg1, msg2; uint32 minor; int msg_ctx; static char *ret; @@ -71,6 +70,8 @@ const char *ads_errstr(ADS_STATUS status) case ADS_ERROR_KRB5: return error_message(status.rc); case ADS_ERROR_GSS: + { + gss_buffer_desc msg1, msg2; msg1.value = NULL; msg2.value = NULL; gss_display_status(&minor, status.rc, GSS_C_GSS_CODE, @@ -81,6 +82,7 @@ const char *ads_errstr(ADS_STATUS status) gss_release_buffer(&minor, &msg1); gss_release_buffer(&minor, &msg2); return ret; + } #endif default: return "Unknown ADS error type!? (not compiled in?)"; -- cgit From 8536aa5ef3147b5ebf29ff114797a039d02213bf Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 31 Dec 2001 11:14:38 +0000 Subject: Allow this to build without LDAP, as per the example below it. Andrew Bartlett (This used to be commit f60e4450018fc06c9f8ce18e62c29fd968d55daa) --- source3/libads/krb5_setpw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index e15c22091d..3973b424f6 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -390,7 +390,7 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char krb5_free_principal(context, principal); krb5_free_context(context); DEBUG(1,("send of chpw failed (%s)\n", strerror(errno))); - return ADS_ERROR(LDAP_ENCODING_ERROR); + return ADS_ERROR_SYSTEM(errno); } free(chpw_req.data); -- cgit From 162a6606bdcb075c256980fb3a559e59d89f2192 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 31 Dec 2001 14:31:13 +0000 Subject: cope with systems that don't have full gssapi libs (This used to be commit c4d928e55fe99a3a1c4e53508a44949f92d74219) --- source3/libads/ads_status.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ads_status.c b/source3/libads/ads_status.c index 51be9c806a..a28fd7b671 100644 --- a/source3/libads/ads_status.c +++ b/source3/libads/ads_status.c @@ -69,6 +69,8 @@ const char *ads_errstr(ADS_STATUS status) #ifdef HAVE_KRB5 case ADS_ERROR_KRB5: return error_message(status.rc); +#endif +#ifdef HAVE_GSSAPI case ADS_ERROR_GSS: { gss_buffer_desc msg1, msg2; -- cgit From b5666e2874a80ce5739e837e4ddc54dc68df7631 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 1 Jan 2002 02:31:32 +0000 Subject: Fix up C99 comment. // -> /* */ (This used to be commit a308abbab717df56b982adf1717da96603d2045f) --- source3/libads/krb5_setpw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 3973b424f6..78d5997c01 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -319,7 +319,7 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char return ADS_ERROR_KRB5(ret); } - //we might have to call krb5_free_creds(...) from now on ... + /* we might have to call krb5_free_creds(...) from now on ... */ ret = krb5_mk_req_extended(context, &auth_context, AP_OPTS_USE_SUBKEY, NULL, credsp, &ap_req); if (ret) { -- cgit From 9e0297b3edd01d5c9b7e99881f72421706b4f9e2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 3 Jan 2002 11:59:33 +0000 Subject: added nTSecurityDescriptor field to host acct dump (This used to be commit f383e19e095eab975bf3d4e622a5c1d1f823171b) --- source3/libads/ldap.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 5503b6e353..c616f09b6e 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -111,11 +111,12 @@ ADS_STATUS ads_find_machine_acct(ADS_STRUCT *ads, void **res, const char *host) { ADS_STATUS status; char *exp; + const char *attrs[] = {"*", "nTSecurityDescriptor", NULL}; /* the easiest way to find a machine account anywhere in the tree is to look for hostname$ */ asprintf(&exp, "(samAccountName=%s$)", host); - status = ads_search(ads, res, exp, NULL); + status = ads_search(ads, res, exp, attrs); free(exp); return status; } @@ -264,6 +265,7 @@ void ads_dump(ADS_STRUCT *ads, void *res) void (*handler)(const char *, struct berval **); } handlers[] = { {"objectGUID", dump_binary}, + {"nTSecurityDescriptor", dump_binary}, {"objectSid", dump_sid}, {NULL, NULL} }; -- cgit From 4acb3125cd42728e2bb3f971bfb9373decc1d0fb Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 11 Jan 2002 04:50:45 +0000 Subject: Fix up 'net ads join' to delete and rejoin if the account already exists. This fixes up a problem where a machine would join (or downgrade by trust password change) to NT4 membership and not be able to regain full ADS membership until a 'net ads leave'. Andrew Bartlett (This used to be commit ab8ff85f03b25a0dfe4ab63886a10da81207393c) --- source3/libads/ldap.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index c616f09b6e..2e93e11603 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -321,8 +321,13 @@ ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *hostname, const char *org status = ads_find_machine_acct(ads, (void **)&res, host); if (ADS_ERR_OK(status) && ads_count_replies(ads, res) == 1) { - DEBUG(0, ("Host account for %s already exists\n", host)); - return ADS_SUCCESS; + DEBUG(0, ("Host account for %s already exists - deleting for readd\n", host)); + status = ads_leave_realm(ads, host); + if (!ADS_ERR_OK(status)) { + DEBUG(0, ("Failed to delete host '%s' from the '%s' realm.\n", + host, ads->realm)); + return status; + } } status = ads_add_machine_acct(ads, host, org_unit); -- cgit From 6059f407637327b01ce008dd09634e4a3bbf8f1b Mon Sep 17 00:00:00 2001 From: Martin Pool Date: Mon, 14 Jan 2002 06:34:53 +0000 Subject: Move local variable to avoid warning when compiled without GSSAPI. (This used to be commit 312c6d906e64d231ff3c2f37e61d752cc948ee7b) --- source3/libads/ads_status.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_status.c b/source3/libads/ads_status.c index a28fd7b671..d54ce9745a 100644 --- a/source3/libads/ads_status.c +++ b/source3/libads/ads_status.c @@ -52,7 +52,6 @@ NTSTATUS ads_ntstatus(ADS_STATUS rc) */ const char *ads_errstr(ADS_STATUS status) { - uint32 minor; int msg_ctx; static char *ret; @@ -73,6 +72,8 @@ const char *ads_errstr(ADS_STATUS status) #ifdef HAVE_GSSAPI case ADS_ERROR_GSS: { + uint32 minor; + gss_buffer_desc msg1, msg2; msg1.value = NULL; msg2.value = NULL; -- cgit From 9f85d4ad5f2bb5fdb7739b3f90c4bfac705393ce Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 16 Jan 2002 02:22:30 +0000 Subject: much better support for organisational units in ADS join (This used to be commit 7e876057d5e392f85e6fdb0f2c233b0fe76df688) --- source3/libads/ads_struct.c | 36 +++++++++++++++++++++++++----------- source3/libads/ldap.c | 22 +++++++++++++++++++++- 2 files changed, 46 insertions(+), 12 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index 013491eaed..476152f2c2 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -22,14 +22,13 @@ #include "includes.h" -/* return a dn of the form "dc=AA,dc=BB,dc=CC" from a - realm of the form AA.BB.CC +/* return a ldap dn path from a string, given separators and field name caller must free */ -char *ads_build_dn(const char *realm) +char *ads_build_path(const char *realm, const char *sep, const char *field, int reverse) { char *p, *r; - int numdots = 0; + int numbits = 0; char *ret; int len; @@ -38,19 +37,25 @@ char *ads_build_dn(const char *realm) if (!r || !*r) return r; for (p=r; *p; p++) { - if (*p == '.') numdots++; + if (strchr(sep, *p)) numbits++; } - len = (numdots+1)*4 + strlen(r) + 1; + len = (numbits+1)*(strlen(field)+1) + strlen(r) + 1; ret = malloc(len); - strlcpy(ret,"dc=", len); - p=strtok(r,"."); + strlcpy(ret,field, len); + p=strtok(r,sep); strlcat(ret, p, len); - while ((p=strtok(NULL,"."))) { - strlcat(ret,",dc=", len); - strlcat(ret, p, len); + while ((p=strtok(NULL,sep))) { + char *s; + if (reverse) { + asprintf(&s, "%s%s,%s", field, p, ret); + } else { + asprintf(&s, "%s,%s%s", ret, field, p); + } + free(ret); + ret = s; } free(r); @@ -58,6 +63,15 @@ char *ads_build_dn(const char *realm) return ret; } +/* return a dn of the form "dc=AA,dc=BB,dc=CC" from a + realm of the form AA.BB.CC + caller must free +*/ +char *ads_build_dn(const char *realm) +{ + return ads_build_path(realm, ".", "dc=", 0); +} + #ifdef HAVE_LDAP /* diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 2e93e11603..d922e4c7c5 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -172,6 +172,23 @@ ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ...) return ADS_ERROR(ret); } +/* + build an org unit string + if org unit is Computers or blank then assume a container, otherwise + assume a \ separated list of organisational units + caller must free +*/ +char *ads_ou_string(const char *org_unit) +{ + if (!org_unit || !*org_unit || strcasecmp(org_unit, "Computers") == 0) { + return strdup("cn=Computers"); + } + + return ads_build_path(org_unit, "\\/", "ou=", 1); +} + + + /* add a machine account to the ADS server */ @@ -180,10 +197,13 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, { ADS_STATUS ret; char *host_spn, *host_upn, *new_dn, *samAccountName, *controlstr; + char *ou_str; asprintf(&host_spn, "HOST/%s", hostname); asprintf(&host_upn, "%s@%s", host_spn, ads->realm); - asprintf(&new_dn, "cn=%s,cn=%s,%s", hostname, org_unit, ads->bind_path); + ou_str = ads_ou_string(org_unit); + asprintf(&new_dn, "cn=%s,%s,%s", hostname, ou_str, ads->bind_path); + free(ou_str); asprintf(&samAccountName, "%s$", hostname); asprintf(&controlstr, "%u", UF_DONT_EXPIRE_PASSWD | UF_WORKSTATION_TRUST_ACCOUNT | -- cgit From de260eadf956cae8aeaebc2a84f46a57c0671741 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 25 Jan 2002 22:07:46 +0000 Subject: Enable net ads commands to use existing tickets if the user doesn't specify a username on the commandline. Also don't continue past the kinit if a password is entered and fails because existing tickets would be used, which may not be desired if the username was specified. (This used to be commit 7e5d7dfa834c0161460bde8a2f0d4824c0a0d1fe) --- source3/libads/ldap.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index d922e4c7c5..d7d2163281 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -31,6 +31,7 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) { int version = LDAP_VERSION3; + int code; ADS_STATUS status; ads->last_attempt = time(NULL); @@ -48,7 +49,8 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); if (ads->password) { - ads_kinit_password(ads); + if ((code = ads_kinit_password(ads))) + return ADS_ERROR_KRB5(code); } return ads_sasl_bind(ads); -- cgit From cd68afe31256ad60748b34f7318a180cfc2127cc Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 30 Jan 2002 06:08:46 +0000 Subject: Removed version number from file header. Changed "SMB/Netbios" to "SMB/CIFS" in file header. (This used to be commit 6a58c9bd06d0d7502a24bf5ce5a2faf0a146edfa) --- source3/libads/ads_status.c | 3 +-- source3/libads/ads_struct.c | 3 +-- source3/libads/kerberos.c | 3 +-- source3/libads/krb5_setpw.c | 3 +-- source3/libads/ldap.c | 3 +-- source3/libads/sasl.c | 3 +-- source3/libads/util.c | 3 +-- 7 files changed, 7 insertions(+), 14 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_status.c b/source3/libads/ads_status.c index d54ce9745a..2d1830435f 100644 --- a/source3/libads/ads_status.c +++ b/source3/libads/ads_status.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 3.0 + Unix SMB/CIFS implementation. ads (active directory) utility library Copyright (C) Andrew Tridgell 2001 Copyright (C) Remus Koos 2001 diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index 476152f2c2..489f301ae2 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 3.0 + Unix SMB/CIFS implementation. ads (active directory) utility library Copyright (C) Andrew Tridgell 2001 Copyright (C) Andrew Bartlett 2001 diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index aba22e023b..194a71275e 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 3.0 + Unix SMB/CIFS implementation. kerberos utility library Copyright (C) Andrew Tridgell 2001 Copyright (C) Remus Koos 2001 diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 78d5997c01..ec79a8658f 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 3.0 + Unix SMB/CIFS implementation. krb5 set password implementation Copyright (C) Andrew Tridgell 2001 Copyright (C) Remus Koos 2001 (remuskoos@yahoo.com) diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index d7d2163281..0028d11b8f 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 3.0 + Unix SMB/CIFS implementation. ads (active directory) utility library Copyright (C) Andrew Tridgell 2001 Copyright (C) Remus Koos 2001 diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 48873252f0..eb29c71fce 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 3.0 + Unix SMB/CIFS implementation. ads sasl code Copyright (C) Andrew Tridgell 2001 diff --git a/source3/libads/util.c b/source3/libads/util.c index 8f22adb7af..d48eb10b71 100644 --- a/source3/libads/util.c +++ b/source3/libads/util.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 3.0 + Unix SMB/CIFS implementation. krb5 set password implementation Copyright (C) Remus Koos 2001 (remuskoos@yahoo.com) -- cgit From 9e75e5c1f0026459bf95985d19558bd157400a26 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 1 Feb 2002 16:14:33 +0000 Subject: Add functions for modifying an entry in ADS. Needed for printer publishing. (This used to be commit 3d8d8cef64c674f9f1240759a05766db95bfde4e) --- source3/libads/ldap.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 118 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 0028d11b8f..ff927bc63c 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -3,7 +3,7 @@ ads (active directory) utility library Copyright (C) Andrew Tridgell 2001 Copyright (C) Remus Koos 2001 - + Copyright (C) Jim McDonough 2002 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -122,6 +122,123 @@ ADS_STATUS ads_find_machine_acct(ADS_STRUCT *ads, void **res, const char *host) return status; } +/* + initialize a list of mods +*/ + +LDAPMod **ads_mod_list_start(int num_mods) +{ + LDAPMod **mods; + + if (num_mods < 1) + return NULL; + + mods = malloc(sizeof(LDAPMod *) * (num_mods + 1)); + memset(mods, 0, sizeof(LDAPMod *) * num_mods); + mods[num_mods] = (LDAPMod *) -1; + + return mods; +} + +/* + add an attribute to the list, with values list already constructed +*/ +static BOOL ads_mod_list_add(LDAPMod **mods, int mod_op, char *name, char **values) +{ + int curmod; + + /* find the first empty slot */ + for (curmod=0; mods[curmod] > 0; curmod++); + if (mods[curmod] == (LDAPMod *) -1) + return False; + + mods[curmod] = malloc(sizeof(LDAPMod)); + mods[curmod]->mod_type = name; + mods[curmod]->mod_values = values; + mods[curmod]->mod_op = mod_op; + return True; +} + +BOOL ads_mod_add_list(LDAPMod **mods, char *name, char **values) +{ + return ads_mod_list_add(mods, LDAP_MOD_ADD, name, values); +} + +BOOL ads_mod_repl_list(LDAPMod **mods, char *name, char **values) +{ + if (values && *values) + return ads_mod_list_add(mods, LDAP_MOD_REPLACE, name, values); + else + return ads_mod_list_add(mods, LDAP_MOD_DELETE, name, NULL); +} + +/* + add an attribute to the list, with values list to be built from args +*/ +BOOL ads_mod_list_add_var(LDAPMod **mods, int mod_op, char *name, ...) +{ + va_list ap; + int num_vals, i; + char *value, **values; + + /* count the number of values */ + va_start(ap, name); + for (num_vals=0; va_arg(ap, char *); num_vals++); + va_end(ap); + + + if (num_vals) { + values = malloc(sizeof(char *) * (num_vals + 1)); + va_start(ap, name); + for (i=0; (value = (char *) va_arg(ap, char *)) && + i < num_vals; i++) + values[i] = value; + va_end(ap); + values[i] = NULL; + } else + values = NULL; + return ads_mod_list_add(mods, mod_op, name, values); +} + +BOOL ads_mod_repl(LDAPMod **mods, char *name, char *val) +{ + if (val) + return ads_mod_list_add_var(mods, LDAP_MOD_REPLACE, name, val); + else + return ads_mod_list_add_var(mods, LDAP_MOD_DELETE, name, NULL); +} + +BOOL ads_mod_add(LDAPMod **mods, char *name, char *val) +{ + return ads_mod_list_add_var(mods, LDAP_MOD_ADD, name, val); +} + +void ads_mod_list_end(LDAPMod **mods) +{ + int i; + + if (mods) { + for (i = 0; mods[i]; i++) { + if (mods[i]->mod_values) { + free(mods[i]->mod_values); + } + free(mods[i]); + } + free(mods); + } +} + +ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, LDAPMod **mods) +{ + int ret,i; + + /* find the end of the list, marked by NULL or -1 */ + for(i=0;mods[i]>0;i++); + /* make sure the end of the list is NULL */ + mods[i] = NULL; + ret = ldap_add_s(ads->ld, mod_dn, mods); + return ADS_ERROR(ret); +} /* a convenient routine for adding a generic LDAP record -- cgit From ecc2e1e3b8981fd72217ed513f2bab1ded46006d Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 1 Feb 2002 16:15:53 +0000 Subject: Module for ADS operations on a printer object in the directory. Initially it creates and modifies a printQueue object in the directory (This used to be commit b14e638aeb80bad80cfd12ed60f5e77f24addfd5) --- source3/libads/ldap_printer.c | 133 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 source3/libads/ldap_printer.c (limited to 'source3/libads') diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c new file mode 100644 index 0000000000..eef8788909 --- /dev/null +++ b/source3/libads/ldap_printer.c @@ -0,0 +1,133 @@ +/* + Unix SMB/CIFS implementation. + ads (active directory) utility library + Copyright (C) Andrew Tridgell 2001 + Copyright (C) Remus Koos 2001 + Copyright (C) Jim McDonough 2002 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +#ifdef HAVE_ADS + +/* + modify an entire printer entry in the directory +*/ +ADS_STATUS ads_mod_printer_entry(ADS_STRUCT *ads, char *prt_dn, + const ADS_PRINTER_ENTRY *prt) +{ + LDAPMod **mods; + ADS_STATUS status; + + /* allocate the list */ + mods = ads_mod_list_start(sizeof(prt) / sizeof(char *)); + + /* add the attributes to the list - required ones first */ + ads_mod_repl(mods, "printerName", prt->printerName); + ads_mod_repl(mods, "serverName", prt->serverName); + ads_mod_repl(mods, "shortServerName", prt->shortServerName); + ads_mod_repl(mods, "uNCName", prt->uNCName); + ads_mod_repl(mods, "versionNumber", prt->versionNumber); + /* now the optional ones */ + ads_mod_repl_list(mods, "description", prt->description); + ads_mod_repl(mods, "driverName", prt->driverName); + ads_mod_repl(mods, "location", prt->location); + ads_mod_repl_list(mods, "portName", prt->portName); + ads_mod_repl(mods, "printStartTime", prt->printStartTime); + ads_mod_repl(mods, "printEndTime", prt->printEndTime); + ads_mod_repl_list(mods, "printBinNames", prt->printBinNames); + + /* and many others */ + + /* do the ldap modify */ + status = ads_gen_mod(ads, prt_dn, mods); + + /* free mod list, mods, and values */ + ads_mod_list_end(mods); + + return status; +} + + +/* + add a printer to the directory +*/ +static ADS_STATUS ads_add_printer_entry(ADS_STRUCT *ads, char *prt_dn, + const ADS_PRINTER_ENTRY *prt) +{ + ADS_STATUS status; + + /* These are the fields a printQueue must contain */ + status = ads_gen_add(ads, prt_dn, + "uNCName", prt->uNCName, NULL, + "versionNumber", prt->versionNumber, NULL, + "serverName", prt->serverName, NULL, + "shortServerName", prt->shortServerName, NULL, + "printerName", prt->printerName, NULL, + "objectClass", "printQueue", NULL, + NULL); + + return status; +} + +/* + publish a printer in the ADS +*/ + +ADS_STATUS ads_add_printer(ADS_STRUCT *ads, const ADS_PRINTER_ENTRY *prt) +{ + ADS_STATUS status; + void *res; + char *host_dn, *prt_dn; + const char *attrs[] = {"*", "nTSecurityDescriptor", NULL}; + + status = ads_find_machine_acct(ads, (void **)&res, + prt->shortServerName); + if (!ADS_ERR_OK(status)) { + DEBUG(1, ("ads_add_printer: cannot find host %s in ads\n", + prt->shortServerName)); + return status; + } + host_dn = ldap_get_dn(ads->ld, res); + ads_msgfree(ads, res); + + /* printer dn is cn=server-printer followed by host dn */ + asprintf(&prt_dn, "cn=%s-%s,%s", prt->shortServerName, + prt->printerName, host_dn); + + status = ads_search_dn(ads, res, prt_dn, attrs); + + if (ADS_ERR_OK(status) && ads_count_replies(ads, res)) { + DEBUG(1, ("ads_add_printer: printer %s already exists\n", + prt->printerName)); + /* nothing to do, just free results */ + ads_msgfree(ads, res); + } else { + ads_msgfree(ads, res); + status = ads_add_printer_entry(ads, prt_dn, prt); + if (!ADS_ERR_OK(status)) { + DEBUG(0, ("ads_add_printer: ads_add_printer_entry failed\n")); + return status; + } + } + + status = ads_mod_printer_entry(ads, prt_dn, prt); + + return status; +} + +#endif -- cgit From aa8ebe3956aaec908a808e24ed8d83073a3e9ee3 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 1 Feb 2002 16:58:01 +0000 Subject: Fix file header description and copyright (from cut-and-paste laziness) (This used to be commit 146c731c35beecd3ae8e093e52d94af0e2efcd69) --- source3/libads/ldap_printer.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index eef8788909..65fa649785 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -1,8 +1,6 @@ /* Unix SMB/CIFS implementation. - ads (active directory) utility library - Copyright (C) Andrew Tridgell 2001 - Copyright (C) Remus Koos 2001 + ads (active directory) printer utility library Copyright (C) Jim McDonough 2002 This program is free software; you can redistribute it and/or modify -- cgit From 0c63216603fa957e04688d22bf1c0321fb2ff78a Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 1 Feb 2002 17:13:39 +0000 Subject: Fix build errors on non-ldap systems...change function parms from LDAPMod ** to void ** (This used to be commit 9467792843fdd9bc55e92bfaa2f2205279074297) --- source3/libads/ldap.c | 51 +++++++++++++++++++++++-------------------- source3/libads/ldap_printer.c | 2 +- 2 files changed, 28 insertions(+), 25 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index ff927bc63c..293c885342 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -123,10 +123,11 @@ ADS_STATUS ads_find_machine_acct(ADS_STRUCT *ads, void **res, const char *host) } /* - initialize a list of mods + initialize a list of mods - returns (void **) instead of (LDAPMod **) + so proto.h works on non-ldap systems */ -LDAPMod **ads_mod_list_start(int num_mods) +void **ads_mod_list_start(int num_mods) { LDAPMod **mods; @@ -137,34 +138,35 @@ LDAPMod **ads_mod_list_start(int num_mods) memset(mods, 0, sizeof(LDAPMod *) * num_mods); mods[num_mods] = (LDAPMod *) -1; - return mods; + return (void **) mods; } /* add an attribute to the list, with values list already constructed */ -static BOOL ads_mod_list_add(LDAPMod **mods, int mod_op, char *name, char **values) +static BOOL ads_mod_list_add(void **mods, int mod_op, char *name, char **values) { int curmod; + LDAPMod **modlist = (LDAPMod **) mods; /* find the first empty slot */ - for (curmod=0; mods[curmod] > 0; curmod++); - if (mods[curmod] == (LDAPMod *) -1) + for (curmod=0; modlist[curmod] > 0; curmod++); + if (modlist[curmod] == (LDAPMod *) -1) return False; - mods[curmod] = malloc(sizeof(LDAPMod)); - mods[curmod]->mod_type = name; - mods[curmod]->mod_values = values; - mods[curmod]->mod_op = mod_op; + modlist[curmod] = malloc(sizeof(LDAPMod)); + modlist[curmod]->mod_type = name; + modlist[curmod]->mod_values = values; + modlist[curmod]->mod_op = mod_op; return True; } -BOOL ads_mod_add_list(LDAPMod **mods, char *name, char **values) +BOOL ads_mod_add_list(void **mods, char *name, char **values) { return ads_mod_list_add(mods, LDAP_MOD_ADD, name, values); } -BOOL ads_mod_repl_list(LDAPMod **mods, char *name, char **values) +BOOL ads_mod_repl_list(void **mods, char *name, char **values) { if (values && *values) return ads_mod_list_add(mods, LDAP_MOD_REPLACE, name, values); @@ -175,7 +177,7 @@ BOOL ads_mod_repl_list(LDAPMod **mods, char *name, char **values) /* add an attribute to the list, with values list to be built from args */ -BOOL ads_mod_list_add_var(LDAPMod **mods, int mod_op, char *name, ...) +BOOL ads_mod_list_add_var(void **mods, int mod_op, char *name, ...) { va_list ap; int num_vals, i; @@ -200,7 +202,7 @@ BOOL ads_mod_list_add_var(LDAPMod **mods, int mod_op, char *name, ...) return ads_mod_list_add(mods, mod_op, name, values); } -BOOL ads_mod_repl(LDAPMod **mods, char *name, char *val) +BOOL ads_mod_repl(void **mods, char *name, char *val) { if (val) return ads_mod_list_add_var(mods, LDAP_MOD_REPLACE, name, val); @@ -208,27 +210,28 @@ BOOL ads_mod_repl(LDAPMod **mods, char *name, char *val) return ads_mod_list_add_var(mods, LDAP_MOD_DELETE, name, NULL); } -BOOL ads_mod_add(LDAPMod **mods, char *name, char *val) +BOOL ads_mod_add(void **mods, char *name, char *val) { return ads_mod_list_add_var(mods, LDAP_MOD_ADD, name, val); } -void ads_mod_list_end(LDAPMod **mods) +void ads_mod_list_end(void **mods) { int i; + LDAPMod **modlist = (LDAPMod **) mods; - if (mods) { - for (i = 0; mods[i]; i++) { - if (mods[i]->mod_values) { - free(mods[i]->mod_values); + if (modlist) { + for (i = 0; modlist[i]; i++) { + if (modlist[i]->mod_values) { + free(modlist[i]->mod_values); } - free(mods[i]); + free(modlist[i]); } - free(mods); + free(modlist); } } -ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, LDAPMod **mods) +ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, void **mods) { int ret,i; @@ -236,7 +239,7 @@ ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, LDAPMod **mods) for(i=0;mods[i]>0;i++); /* make sure the end of the list is NULL */ mods[i] = NULL; - ret = ldap_add_s(ads->ld, mod_dn, mods); + ret = ldap_add_s(ads->ld, mod_dn, (LDAPMod **) mods); return ADS_ERROR(ret); } diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index 65fa649785..54cd7d8e94 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -28,7 +28,7 @@ ADS_STATUS ads_mod_printer_entry(ADS_STRUCT *ads, char *prt_dn, const ADS_PRINTER_ENTRY *prt) { - LDAPMod **mods; + void **mods; ADS_STATUS status; /* allocate the list */ -- cgit From bb8349735f627ba4de2012f77ee3fa6ce491f394 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Sat, 2 Feb 2002 02:04:01 +0000 Subject: Minor bug fixes, plus support to remove a printer. Commented out optional attributes until a method for checking for their existence is done. (This used to be commit 538c19a6983e0423b94f743184263cd8ef9c701e) --- source3/libads/ldap.c | 67 ++++++++++++++++++++++++++++++++++++------- source3/libads/ldap_printer.c | 40 ++++++++++++++++++++++---- 2 files changed, 91 insertions(+), 16 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 293c885342..8dee73bde2 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -105,6 +105,23 @@ void ads_msgfree(ADS_STRUCT *ads, void *msg) ldap_msgfree(msg); } +/* + free up memory from various ads requests +*/ +void ads_memfree(ADS_STRUCT *ads, void *mem) +{ + if (!mem) return; + ldap_memfree(mem); +} + +/* + get a dn from search results +*/ +char *ads_get_dn(ADS_STRUCT *ads, void *res) +{ + return ldap_get_dn(ads->ld, res); +} + /* find a machine account given a hostname */ @@ -122,6 +139,24 @@ ADS_STATUS ads_find_machine_acct(ADS_STRUCT *ads, void **res, const char *host) return status; } +/* + duplicate an already-assembled list of values so that it can be + freed as part of the standard msgfree call +*/ +static char **ads_dup_values(char **values) +{ + char **newvals; + int i; +#define ADS_MAX_NUM_VALUES 32 + + for (i=0; values[i] && i0;i++); /* make sure the end of the list is NULL */ mods[i] = NULL; - ret = ldap_add_s(ads->ld, mod_dn, (LDAPMod **) mods); + ret = ldap_modify_s(ads->ld, mod_dn, (LDAPMod **) mods); return ADS_ERROR(ret); } @@ -293,6 +333,11 @@ ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ...) return ADS_ERROR(ret); } +ADS_STATUS ads_del_dn(ADS_STRUCT *ads, char *del_dn) +{ + return ADS_ERROR(ldap_delete(ads->ld, del_dn)); +} + /* build an org unit string if org unit is Computers or blank then assume a container, otherwise @@ -508,9 +553,9 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) return status; } - hostnameDN = ldap_get_dn(ads->ld, (LDAPMessage *)res); + hostnameDN = ads_get_dn(ads, (LDAPMessage *)res); rc = ldap_delete_s(ads->ld, hostnameDN); - ldap_memfree(hostnameDN); + ads_memfree(ads, hostnameDN); if (rc != LDAP_SUCCESS) { return ADS_ERROR(rc); } diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index 54cd7d8e94..74dc02397c 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -22,6 +22,35 @@ #ifdef HAVE_ADS +/* + find a printer given the name and the hostname + Note that results "res" may be allocated on return so that the + results can be used. It should be freed using ads_msgfree. +*/ +ADS_STATUS ads_find_printer_on_server(ADS_STRUCT *ads, void **res, + char *printer, char *servername) +{ + ADS_STATUS status; + char *srv_dn, *exp; + const char *attrs[] = {"*", "nTSecurityDescriptor", NULL}; + + status = ads_find_machine_acct(ads, res, servername); + if (!ADS_ERR_OK(status)) { + DEBUG(1, ("ads_add_printer: cannot find host %s in ads\n", + servername)); + return status; + } + srv_dn = ldap_get_dn(ads->ld, *res); + ads_msgfree(ads, *res); + + asprintf(&exp, "(printerName=%s)", printer); + status = ads_do_search(ads, srv_dn, LDAP_SCOPE_SUBTREE, + exp, &attrs, res); + + free(exp); + return status; +} + /* modify an entire printer entry in the directory */ @@ -32,7 +61,7 @@ ADS_STATUS ads_mod_printer_entry(ADS_STRUCT *ads, char *prt_dn, ADS_STATUS status; /* allocate the list */ - mods = ads_mod_list_start(sizeof(prt) / sizeof(char *)); + mods = ads_mod_list_start(sizeof(ADS_PRINTER_ENTRY) / sizeof(char *)); /* add the attributes to the list - required ones first */ ads_mod_repl(mods, "printerName", prt->printerName); @@ -40,7 +69,8 @@ ADS_STATUS ads_mod_printer_entry(ADS_STRUCT *ads, char *prt_dn, ads_mod_repl(mods, "shortServerName", prt->shortServerName); ads_mod_repl(mods, "uNCName", prt->uNCName); ads_mod_repl(mods, "versionNumber", prt->versionNumber); - /* now the optional ones */ + /* now the optional ones - not ready yet, since it will + fail if the attributes don't exist already ads_mod_repl_list(mods, "description", prt->description); ads_mod_repl(mods, "driverName", prt->driverName); ads_mod_repl(mods, "location", prt->location); @@ -49,7 +79,7 @@ ADS_STATUS ads_mod_printer_entry(ADS_STRUCT *ads, char *prt_dn, ads_mod_repl(mods, "printEndTime", prt->printEndTime); ads_mod_repl_list(mods, "printBinNames", prt->printBinNames); - /* and many others */ + ... and many others */ /* do the ldap modify */ status = ads_gen_mod(ads, prt_dn, mods); @@ -93,7 +123,7 @@ ADS_STATUS ads_add_printer(ADS_STRUCT *ads, const ADS_PRINTER_ENTRY *prt) char *host_dn, *prt_dn; const char *attrs[] = {"*", "nTSecurityDescriptor", NULL}; - status = ads_find_machine_acct(ads, (void **)&res, + status = ads_find_machine_acct(ads, (void **)&res, prt->shortServerName); if (!ADS_ERR_OK(status)) { DEBUG(1, ("ads_add_printer: cannot find host %s in ads\n", @@ -107,7 +137,7 @@ ADS_STATUS ads_add_printer(ADS_STRUCT *ads, const ADS_PRINTER_ENTRY *prt) asprintf(&prt_dn, "cn=%s-%s,%s", prt->shortServerName, prt->printerName, host_dn); - status = ads_search_dn(ads, res, prt_dn, attrs); + status = ads_search_dn(ads, &res, prt_dn, attrs); if (ADS_ERR_OK(status) && ads_count_replies(ads, res)) { DEBUG(1, ("ads_add_printer: printer %s already exists\n", -- cgit From 81b54940b7e9a3a3f6586972b1c9aa687e07426d Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Sat, 2 Feb 2002 22:06:10 +0000 Subject: merge in some changes from Alexey Kotovich. Return ADS_STATUS instead of BOOLs. Add support for bervals in mod lists. Also put undocumented AD ldap control in to allow modifications when an attribute does not yet exist. (This used to be commit 1a2d27b21e61be5a314f7d6c4ea0dff06a5307be) --- source3/libads/ldap.c | 121 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 88 insertions(+), 33 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 8dee73bde2..75c7982105 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -37,7 +37,7 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) ads->ld = ldap_open(ads->ldap_server, ads->ldap_port); if (!ads->ld) { - return ADS_ERROR_SYSTEM(errno) + return ADS_ERROR_SYSTEM(errno); } status = ads_server_info(ads); if (!ADS_ERR_OK(status)) { @@ -150,7 +150,8 @@ static char **ads_dup_values(char **values) #define ADS_MAX_NUM_VALUES 32 for (i=0; values[i] && i 0; curmod++); if (modlist[curmod] == (LDAPMod *) -1) - return False; + return ADS_ERROR(LDAP_NO_MEMORY); - modlist[curmod] = malloc(sizeof(LDAPMod)); + if (!(modlist[curmod] = malloc(sizeof(LDAPMod)))) + return ADS_ERROR(LDAP_NO_MEMORY); modlist[curmod]->mod_type = name; modlist[curmod]->mod_values = values; modlist[curmod]->mod_op = mod_op; - return True; + return ADS_ERROR(LDAP_SUCCESS); } -BOOL ads_mod_add_list(void **mods, char *name, char **values) +ADS_STATUS ads_mod_add_list(void **mods, char *name, char **values) { char **newvals = ads_dup_values(values); - return ads_mod_list_add(mods, LDAP_MOD_ADD, name, newvals); + if (newvals) + return ads_modlist_add(mods, LDAP_MOD_ADD, name, newvals); + else + return ADS_ERROR(LDAP_NO_MEMORY); } -BOOL ads_mod_repl_list(void **mods, char *name, char **values) +ADS_STATUS ads_mod_repl_list(void **mods, char *name, char **values) { char **newvals; if (values && *values) { - newvals = ads_dup_values(values); - return ads_mod_list_add(mods, LDAP_MOD_REPLACE, name, newvals); + if (!(newvals = ads_dup_values(values))) + return ADS_ERROR(LDAP_NO_MEMORY); + else + return ads_modlist_add(mods, LDAP_MOD_REPLACE, + name, newvals); } else - return ads_mod_list_add(mods, LDAP_MOD_DELETE, name, NULL); + return ads_modlist_add(mods, LDAP_MOD_DELETE, name, NULL); } /* add an attribute to the list, with values list to be built from args */ -BOOL ads_mod_list_add_var(void **mods, int mod_op, char *name, ...) +ADS_STATUS ads_mod_add_var(void **mods, int mod_op, char *name, ...) { va_list ap; - int num_vals, i; + int num_vals, i, do_op; char *value, **values; /* count the number of values */ @@ -227,45 +236,75 @@ BOOL ads_mod_list_add_var(void **mods, int mod_op, char *name, ...) for (num_vals=0; va_arg(ap, char *); num_vals++); va_end(ap); + if (num_vals) { + if (!(values = malloc(sizeof(char *) * (num_vals + 1)))) + return ADS_ERROR(LDAP_NO_MEMORY); + va_start(ap, name); + for (i=0; (value = (char *) va_arg(ap, char *)) && + i < num_vals; i++) + values[i] = value; + va_end(ap); + values[i] = NULL; + do_op = mod_op; + } else { + do_op = LDAP_MOD_DELETE; + values = NULL; + } + return ads_modlist_add(mods, do_op, name, values); +} + +ADS_STATUS ads_mod_add_ber(void **mods, int mod_op, char *name, ...) +{ + va_list ap; + int num_vals, i, do_op; + char *value, **values; + + /* count the number of values */ + va_start(ap, name); + for (num_vals=0; va_arg(ap, struct berval *); num_vals++); + va_end(ap); if (num_vals) { - values = malloc(sizeof(char *) * (num_vals + 1)); + if (!(values = malloc(sizeof(struct berval) * (num_vals + 1)))) + return ADS_ERROR(LDAP_NO_MEMORY); va_start(ap, name); for (i=0; (value = (char *) va_arg(ap, char *)) && i < num_vals; i++) values[i] = value; va_end(ap); values[i] = NULL; - } else + do_op = mod_op; + } else { + do_op = LDAP_MOD_DELETE; values = NULL; - return ads_mod_list_add(mods, mod_op, name, values); + } + do_op |= LDAP_MOD_BVALUES; + return ads_modlist_add(mods, do_op, name, values); } -BOOL ads_mod_repl(void **mods, char *name, char *val) +ADS_STATUS ads_mod_repl(void **mods, char *name, char *val) { if (val) - return ads_mod_list_add_var(mods, LDAP_MOD_REPLACE, + return ads_mod_add_var(mods, LDAP_MOD_REPLACE, name, val, NULL); else - return ads_mod_list_add_var(mods, LDAP_MOD_DELETE, name, NULL); + return ads_mod_add_var(mods, LDAP_MOD_DELETE, name, NULL); } -BOOL ads_mod_add(void **mods, char *name, char *val) +ADS_STATUS ads_mod_add(void **mods, char *name, char *val) { - return ads_mod_list_add_var(mods, LDAP_MOD_ADD, name, val, NULL); + return ads_mod_add_var(mods, LDAP_MOD_ADD, name, val, NULL); } -void ads_mod_list_end(void **mods) +void ads_free_mods(void **mods) { int i; LDAPMod **modlist = (LDAPMod **) mods; if (modlist) { for (i = 0; modlist[i]; i++) { - if (modlist[i]->mod_values) { - free(modlist[i]->mod_values); - } - free(modlist[i]); + SAFE_FREE(modlist[i]->mod_values); + SAFE_FREE(modlist[i]); } free(modlist); } @@ -274,12 +313,28 @@ void ads_mod_list_end(void **mods) ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, void **mods) { int ret,i; - + LDAPControl control; + LDAPControl *controls[2]; + char bv_val = (char) 1; + + /* + this control seems to be necessary to have any modify + that contains a currently non-existent attribute (but + allowable for the object) to run + */ + control.ldctl_oid = "1.2.840.113556.1.4.1413"; + control.ldctl_value.bv_len = 1; + control.ldctl_value.bv_val = &bv_val; + control.ldctl_iscritical = (char) 0; + controls[0] = &control; + controls[1] = NULL; + /* find the end of the list, marked by NULL or -1 */ for(i=0;mods[i]>0;i++); /* make sure the end of the list is NULL */ mods[i] = NULL; - ret = ldap_modify_s(ads->ld, mod_dn, (LDAPMod **) mods); + ret = ldap_modify_ext_s(ads->ld, mod_dn, (LDAPMod **) mods, + controls, NULL); return ADS_ERROR(ret); } -- cgit From 55b92fdebcddc14981c6eafbe98751b365a5e0ed Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Sat, 2 Feb 2002 22:07:22 +0000 Subject: Update for function name changes, plus do some of the optional attributes on printer modify, now that the ldap control is working. (This used to be commit 76afc886a89e8c0d5a169435dde42b00db522060) --- source3/libads/ldap_printer.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index 74dc02397c..d337398158 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -61,7 +61,7 @@ ADS_STATUS ads_mod_printer_entry(ADS_STRUCT *ads, char *prt_dn, ADS_STATUS status; /* allocate the list */ - mods = ads_mod_list_start(sizeof(ADS_PRINTER_ENTRY) / sizeof(char *)); + mods = ads_init_mods(sizeof(ADS_PRINTER_ENTRY) / sizeof(char *)); /* add the attributes to the list - required ones first */ ads_mod_repl(mods, "printerName", prt->printerName); @@ -69,23 +69,34 @@ ADS_STATUS ads_mod_printer_entry(ADS_STRUCT *ads, char *prt_dn, ads_mod_repl(mods, "shortServerName", prt->shortServerName); ads_mod_repl(mods, "uNCName", prt->uNCName); ads_mod_repl(mods, "versionNumber", prt->versionNumber); - /* now the optional ones - not ready yet, since it will - fail if the attributes don't exist already + + /* now the optional ones */ ads_mod_repl_list(mods, "description", prt->description); + ads_mod_repl(mods, "assetNumber",prt->assetNumber); + ads_mod_repl(mods, "bytesPerMinute",prt->bytesPerMinute); + ads_mod_repl(mods, "defaultPriority",prt->defaultPriority); ads_mod_repl(mods, "driverName", prt->driverName); + ads_mod_repl(mods, "driverVersion",prt->driverVersion); ads_mod_repl(mods, "location", prt->location); + ads_mod_repl(mods, "operatingSystem",prt->operatingSystem); + ads_mod_repl(mods, "operatingSystemHotfix",prt->operatingSystemHotfix); + ads_mod_repl(mods, "operatingSystemServicePack", + prt->operatingSystemServicePack); + ads_mod_repl(mods, "operatingSystemVersion", + prt->operatingSystemVersion); + ads_mod_repl(mods, "physicalLocationObject", + prt->physicalLocationObject); ads_mod_repl_list(mods, "portName", prt->portName); ads_mod_repl(mods, "printStartTime", prt->printStartTime); ads_mod_repl(mods, "printEndTime", prt->printEndTime); ads_mod_repl_list(mods, "printBinNames", prt->printBinNames); - - ... and many others */ + /*... and many others */ /* do the ldap modify */ status = ads_gen_mod(ads, prt_dn, mods); /* free mod list, mods, and values */ - ads_mod_list_end(mods); + ads_free_mods(mods); return status; } -- cgit From 9aa88da9d5500b185299c05103d63c76f527a9dc Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Wed, 6 Feb 2002 02:28:46 +0000 Subject: Fix ldapmod list overrun check. Also better document and format ldap control for permissive modify. (This used to be commit 01e7f7c3d9006883b71e43d917d32e325cff7a15) --- source3/libads/ldap.c | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 75c7982105..4567a42c0f 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -71,7 +71,7 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, rc = ldap_search_ext_s(ads->ld, bind_path, scope, - exp, attrs, 0, NULL, NULL, + exp, (char **) attrs, 0, NULL, NULL, &timeout, LDAP_NO_LIMIT, (LDAPMessage **)res); return ADS_ERROR(rc); } @@ -187,10 +187,11 @@ static ADS_STATUS ads_modlist_add(void **mods, int mod_op, char *name, char **va LDAPMod **modlist = (LDAPMod **) mods; /* find the first empty slot */ - for (curmod=0; modlist[curmod] > 0; curmod++); + for (curmod=0; modlist[curmod] && modlist[curmod] != (LDAPMod *) -1; + curmod++); if (modlist[curmod] == (LDAPMod *) -1) return ADS_ERROR(LDAP_NO_MEMORY); - + if (!(modlist[curmod] = malloc(sizeof(LDAPMod)))) return ADS_ERROR(LDAP_NO_MEMORY); modlist[curmod]->mod_type = name; @@ -313,21 +314,17 @@ void ads_free_mods(void **mods) ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, void **mods) { int ret,i; - LDAPControl control; - LDAPControl *controls[2]; - char bv_val = (char) 1; - /* - this control seems to be necessary to have any modify - that contains a currently non-existent attribute (but - allowable for the object) to run + this control is needed to modify that contains a currently + non-existent attribute (but allowable for the object) to run */ - control.ldctl_oid = "1.2.840.113556.1.4.1413"; - control.ldctl_value.bv_len = 1; - control.ldctl_value.bv_val = &bv_val; - control.ldctl_iscritical = (char) 0; - controls[0] = &control; - controls[1] = NULL; + LDAPControl PermitModify = { + "1.2.840.113556.1.4.1413", + {0, NULL}, + (char) 1}; + LDAPControl *controls[2] = { + &PermitModify, + NULL }; /* find the end of the list, marked by NULL or -1 */ for(i=0;mods[i]>0;i++); -- cgit From fb444a546effe22e2a7c314a10473f0680be0cc6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 7 Feb 2002 02:44:37 +0000 Subject: when a trusted domain is down an ADS server will return a success on a get trusted domains query but leave the domain SID blank - we need to fail the add of the trusted domain in winbindd in that case (This used to be commit 24c7e7a3849df3a3378f7e7f20099de048f0b7bd) --- source3/libads/ldap.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 4567a42c0f..a13bda5fa9 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -855,8 +855,9 @@ ADS_STATUS ads_trusted_domains(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, for (i=0, msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) { (*names)[i] = ads_pull_string(ads, mem_ctx, msg, "flatName"); - ads_pull_sid(ads, msg, "securityIdentifier", &(*sids)[i]); - i++; + if (ads_pull_sid(ads, msg, "securityIdentifier", &(*sids)[i])) { + i++; + } } ads_msgfree(ads, res); -- cgit From d2b65dcbff87e7d6e1f56ddffeaeed4cba2b890d Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Mon, 11 Feb 2002 15:47:02 +0000 Subject: Add ability to extend ads modification list on the fly. Also add some malloc checks and return ADS_ERROR(LDAP_NO_MEMORY) if they fail. (This used to be commit 81d76f05d8b886a86eb421d1bd8737ec7d05cbde) --- source3/libads/ldap.c | 62 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 39 insertions(+), 23 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index a13bda5fa9..e1d7d5d26c 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -163,34 +163,41 @@ static char **ads_dup_values(char **values) so proto.h works on non-ldap systems */ -void **ads_init_mods(int num_mods) +ADS_MODLIST ads_init_mods(void) { +#define ADS_MODLIST_ALLOC_SIZE 10 LDAPMod **mods; - if (num_mods < 1) - return NULL; - - if ((mods = calloc(1, sizeof(LDAPMod *) * (num_mods + 1)))) + if ((mods = calloc(1, sizeof(LDAPMod *) * + (ADS_MODLIST_ALLOC_SIZE + 1)))) /* -1 is safety to make sure we don't go over the end. need to reset it to NULL before doing ldap modify */ - mods[num_mods] = (LDAPMod *) -1; + mods[ADS_MODLIST_ALLOC_SIZE] = (LDAPMod *) -1; - return (void **) mods; + return mods; } /* add an attribute to the list, with values list already constructed */ -static ADS_STATUS ads_modlist_add(void **mods, int mod_op, char *name, char **values) +static ADS_STATUS ads_modlist_add(ADS_MODLIST *mods, int mod_op, char *name, char **values) { int curmod; - LDAPMod **modlist = (LDAPMod **) mods; + LDAPMod **modlist = (LDAPMod **) *mods; /* find the first empty slot */ for (curmod=0; modlist[curmod] && modlist[curmod] != (LDAPMod *) -1; curmod++); - if (modlist[curmod] == (LDAPMod *) -1) - return ADS_ERROR(LDAP_NO_MEMORY); + if (modlist[curmod] == (LDAPMod *) -1) { + modlist = realloc(modlist, (curmod+ADS_MODLIST_ALLOC_SIZE+1) * + sizeof(LDAPMod *)); + if (!modlist) + return ADS_ERROR(LDAP_NO_MEMORY); + memset(&modlist[curmod], 0, + ADS_MODLIST_ALLOC_SIZE*sizeof(LDAPMod *)); + modlist[curmod+ADS_MODLIST_ALLOC_SIZE] = (LDAPMod *) -1; + *mods = modlist; + } if (!(modlist[curmod] = malloc(sizeof(LDAPMod)))) return ADS_ERROR(LDAP_NO_MEMORY); @@ -200,7 +207,7 @@ static ADS_STATUS ads_modlist_add(void **mods, int mod_op, char *name, char **va return ADS_ERROR(LDAP_SUCCESS); } -ADS_STATUS ads_mod_add_list(void **mods, char *name, char **values) +ADS_STATUS ads_mod_add_list(ADS_MODLIST *mods, char *name, char **values) { char **newvals = ads_dup_values(values); if (newvals) @@ -209,7 +216,7 @@ ADS_STATUS ads_mod_add_list(void **mods, char *name, char **values) return ADS_ERROR(LDAP_NO_MEMORY); } -ADS_STATUS ads_mod_repl_list(void **mods, char *name, char **values) +ADS_STATUS ads_mod_repl_list(ADS_MODLIST *mods, char *name, char **values) { char **newvals; if (values && *values) { @@ -226,7 +233,7 @@ ADS_STATUS ads_mod_repl_list(void **mods, char *name, char **values) /* add an attribute to the list, with values list to be built from args */ -ADS_STATUS ads_mod_add_var(void **mods, int mod_op, char *name, ...) +ADS_STATUS ads_mod_add_var(ADS_MODLIST *mods, int mod_op, char *name, ...) { va_list ap; int num_vals, i, do_op; @@ -254,7 +261,7 @@ ADS_STATUS ads_mod_add_var(void **mods, int mod_op, char *name, ...) return ads_modlist_add(mods, do_op, name, values); } -ADS_STATUS ads_mod_add_ber(void **mods, int mod_op, char *name, ...) +ADS_STATUS ads_mod_add_ber(ADS_MODLIST *mods, int mod_op, char *name, ...) { va_list ap; int num_vals, i, do_op; @@ -283,7 +290,7 @@ ADS_STATUS ads_mod_add_ber(void **mods, int mod_op, char *name, ...) return ads_modlist_add(mods, do_op, name, values); } -ADS_STATUS ads_mod_repl(void **mods, char *name, char *val) +ADS_STATUS ads_mod_repl(ADS_MODLIST *mods, char *name, char *val) { if (val) return ads_mod_add_var(mods, LDAP_MOD_REPLACE, @@ -292,12 +299,12 @@ ADS_STATUS ads_mod_repl(void **mods, char *name, char *val) return ads_mod_add_var(mods, LDAP_MOD_DELETE, name, NULL); } -ADS_STATUS ads_mod_add(void **mods, char *name, char *val) +ADS_STATUS ads_mod_add(ADS_MODLIST *mods, char *name, char *val) { return ads_mod_add_var(mods, LDAP_MOD_ADD, name, val, NULL); } -void ads_free_mods(void **mods) +void ads_free_mods(ADS_MODLIST mods) { int i; LDAPMod **modlist = (LDAPMod **) mods; @@ -311,7 +318,7 @@ void ads_free_mods(void **mods) } } -ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, void **mods) +ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, ADS_MODLIST mods) { int ret,i; /* @@ -327,7 +334,7 @@ ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, void **mods) NULL }; /* find the end of the list, marked by NULL or -1 */ - for(i=0;mods[i]>0;i++); + for(i=0;(mods[i]!=0)&&(mods[i]!=(LDAPMod *) -1);i++); /* make sure the end of the list is NULL */ mods[i] = NULL; ret = ldap_modify_ext_s(ads->ld, mod_dn, (LDAPMod **) mods, @@ -355,18 +362,27 @@ ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ...) } va_end(ap); - mods = malloc(sizeof(LDAPMod *) * (i+1)); + if (!(mods = malloc(sizeof(LDAPMod *) * (i+1)))) + return ADS_ERROR(LDAP_NO_MEMORY); va_start(ap, new_dn); for (i=0; (name=va_arg(ap, char *)); i++) { char **values; int j; - values = (char **)malloc(sizeof(char *) * (MAX_MOD_VALUES+1)); + if (!(values = + (char **)malloc(sizeof(char *) * (MAX_MOD_VALUES+1)))) { + free(mods); + return ADS_ERROR(LDAP_NO_MEMORY); + } for (j=0; (value=va_arg(ap, char *)) && j < MAX_MOD_VALUES; j++) { values[j] = value; } values[j] = NULL; - mods[i] = malloc(sizeof(LDAPMod)); + if (!(mods[i] = malloc(sizeof(LDAPMod)))) { + free(values); + free(mods); + return ADS_ERROR(LDAP_NO_MEMORY); + } mods[i]->mod_type = name; mods[i]->mod_op = LDAP_MOD_ADD; mods[i]->mod_values = values; -- cgit From ad6dfee7413756b7fe76ce1c9440105edd2fe9b2 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Mon, 11 Feb 2002 15:48:01 +0000 Subject: Update for new ads modlist structure passing (This used to be commit 6169b668fe955f298c7323c5d64f6c7b303aaac0) --- source3/libads/ldap_printer.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index d337398158..50f4302201 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -57,11 +57,11 @@ ADS_STATUS ads_find_printer_on_server(ADS_STRUCT *ads, void **res, ADS_STATUS ads_mod_printer_entry(ADS_STRUCT *ads, char *prt_dn, const ADS_PRINTER_ENTRY *prt) { - void **mods; + ADS_MODLIST *mods; ADS_STATUS status; /* allocate the list */ - mods = ads_init_mods(sizeof(ADS_PRINTER_ENTRY) / sizeof(char *)); + *mods = ads_init_mods(); /* add the attributes to the list - required ones first */ ads_mod_repl(mods, "printerName", prt->printerName); @@ -93,10 +93,10 @@ ADS_STATUS ads_mod_printer_entry(ADS_STRUCT *ads, char *prt_dn, /*... and many others */ /* do the ldap modify */ - status = ads_gen_mod(ads, prt_dn, mods); + status = ads_gen_mod(ads, prt_dn, *mods); /* free mod list, mods, and values */ - ads_free_mods(mods); + ads_free_mods(*mods); return status; } @@ -164,7 +164,16 @@ ADS_STATUS ads_add_printer(ADS_STRUCT *ads, const ADS_PRINTER_ENTRY *prt) } } - status = ads_mod_printer_entry(ads, prt_dn, prt); + status = ads_search_dn(ads, &res, prt_dn, attrs); + + if (ADS_ERR_OK(status) && ads_count_replies(ads, res)) { + /* need to retrieve GUID from results + prt->GUID */ + status = ads_mod_printer_entry(ads, prt_dn, prt); + } + + ads_msgfree(ads, res); + return status; } -- cgit From a346cfb4677fcfcb5900e3a299bf7bc0bc76f758 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Tue, 12 Feb 2002 18:22:33 +0000 Subject: talloc'ify ads modify functions. Also add more complete berval support. (This used to be commit 1f186c60ad957c0e8157a6fd903857121c65a2e0) --- source3/libads/ldap.c | 241 +++++++++++++++++++++++++------------------------- 1 file changed, 119 insertions(+), 122 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index e1d7d5d26c..682524eb4f 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -143,14 +143,14 @@ ADS_STATUS ads_find_machine_acct(ADS_STRUCT *ads, void **res, const char *host) duplicate an already-assembled list of values so that it can be freed as part of the standard msgfree call */ -static char **ads_dup_values(char **values) +static char **ads_dup_values(TALLOC_CTX *ctx, char **values) { char **newvals; int i; #define ADS_MAX_NUM_VALUES 32 for (i=0; values[i] && imod_type = name; - modlist[curmod]->mod_values = values; + if (mod_op & LDAP_MOD_BVALUES) + modlist[curmod]->mod_bvalues = (struct berval **) values; + else + modlist[curmod]->mod_values = values; modlist[curmod]->mod_op = mod_op; return ADS_ERROR(LDAP_SUCCESS); } -ADS_STATUS ads_mod_add_list(ADS_MODLIST *mods, char *name, char **values) +ADS_STATUS ads_mod_add_list(TALLOC_CTX *ctx, ADS_MODLIST *mods, + char *name, char **values) { - char **newvals = ads_dup_values(values); + char **newvals = ads_dup_values(ctx, values); if (newvals) - return ads_modlist_add(mods, LDAP_MOD_ADD, name, newvals); + return ads_modlist_add(ctx, mods, LDAP_MOD_ADD, name, newvals); else return ADS_ERROR(LDAP_NO_MEMORY); } -ADS_STATUS ads_mod_repl_list(ADS_MODLIST *mods, char *name, char **values) +ADS_STATUS ads_mod_repl_list(TALLOC_CTX *ctx, ADS_MODLIST *mods, + char *name, char **values) { char **newvals; if (values && *values) { - if (!(newvals = ads_dup_values(values))) + if (!(newvals = ads_dup_values(ctx, values))) return ADS_ERROR(LDAP_NO_MEMORY); else - return ads_modlist_add(mods, LDAP_MOD_REPLACE, + return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE, name, newvals); } else - return ads_modlist_add(mods, LDAP_MOD_DELETE, name, NULL); + return ads_modlist_add(ctx, mods, LDAP_MOD_DELETE, name, NULL); } /* add an attribute to the list, with values list to be built from args */ -ADS_STATUS ads_mod_add_var(ADS_MODLIST *mods, int mod_op, char *name, ...) +ADS_STATUS ads_mod_add_var(TALLOC_CTX *ctx, ADS_MODLIST *mods, + int mod_op, char *name, ...) { va_list ap; int num_vals, i, do_op; @@ -245,7 +250,7 @@ ADS_STATUS ads_mod_add_var(ADS_MODLIST *mods, int mod_op, char *name, ...) va_end(ap); if (num_vals) { - if (!(values = malloc(sizeof(char *) * (num_vals + 1)))) + if (!(values = talloc_zero(ctx, sizeof(char *)*(num_vals+1)))) return ADS_ERROR(LDAP_NO_MEMORY); va_start(ap, name); for (i=0; (value = (char *) va_arg(ap, char *)) && @@ -258,10 +263,11 @@ ADS_STATUS ads_mod_add_var(ADS_MODLIST *mods, int mod_op, char *name, ...) do_op = LDAP_MOD_DELETE; values = NULL; } - return ads_modlist_add(mods, do_op, name, values); + return ads_modlist_add(ctx, mods, do_op, name, values); } -ADS_STATUS ads_mod_add_ber(ADS_MODLIST *mods, int mod_op, char *name, ...) +ADS_STATUS ads_mod_add_ber(TALLOC_CTX *ctx, ADS_MODLIST *mods, + int mod_op, char *name, ...) { va_list ap; int num_vals, i, do_op; @@ -273,7 +279,8 @@ ADS_STATUS ads_mod_add_ber(ADS_MODLIST *mods, int mod_op, char *name, ...) va_end(ap); if (num_vals) { - if (!(values = malloc(sizeof(struct berval) * (num_vals + 1)))) + if (!(values = talloc_zero(ctx, sizeof(struct berval) * + (num_vals + 1)))) return ADS_ERROR(LDAP_NO_MEMORY); va_start(ap, name); for (i=0; (value = (char *) va_arg(ap, char *)) && @@ -287,34 +294,57 @@ ADS_STATUS ads_mod_add_ber(ADS_MODLIST *mods, int mod_op, char *name, ...) values = NULL; } do_op |= LDAP_MOD_BVALUES; - return ads_modlist_add(mods, do_op, name, values); + return ads_modlist_add(ctx, mods, do_op, name, values); } -ADS_STATUS ads_mod_repl(ADS_MODLIST *mods, char *name, char *val) +ADS_STATUS ads_mod_repl(TALLOC_CTX *ctx, ADS_MODLIST *mods, + char *name, char *val) { if (val) - return ads_mod_add_var(mods, LDAP_MOD_REPLACE, - name, val, NULL); + return ads_mod_add_var(ctx, mods, LDAP_MOD_REPLACE, + name, val, NULL); else - return ads_mod_add_var(mods, LDAP_MOD_DELETE, name, NULL); + return ads_mod_add_var(ctx, mods, LDAP_MOD_DELETE, name, NULL); } -ADS_STATUS ads_mod_add(ADS_MODLIST *mods, char *name, char *val) +ADS_STATUS ads_mod_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, + char *name, char *val) { - return ads_mod_add_var(mods, LDAP_MOD_ADD, name, val, NULL); + return ads_mod_add_var(ctx, mods, LDAP_MOD_ADD, name, val, NULL); } -void ads_free_mods(ADS_MODLIST mods) +ADS_STATUS ads_mod_add_len(TALLOC_CTX *ctx, ADS_MODLIST *mods, + char *name, size_t size, char *val) { - int i; - LDAPMod **modlist = (LDAPMod **) mods; - - if (modlist) { - for (i = 0; modlist[i]; i++) { - SAFE_FREE(modlist[i]->mod_values); - SAFE_FREE(modlist[i]); - } - free(modlist); + struct berval *bval = NULL; + + if (!(bval = talloc_zero(ctx, sizeof(struct berval *)))) + return ADS_ERROR(LDAP_NO_MEMORY); + if (!(bval->bv_val = talloc_zero(ctx, sizeof(char *)))) + return ADS_ERROR(LDAP_NO_MEMORY); + + bval->bv_val = val; + bval->bv_len = size; + return ads_mod_add_ber(ctx, mods, LDAP_MOD_ADD, name, bval, NULL); +} + +ADS_STATUS ads_mod_repl_len(TALLOC_CTX *ctx, ADS_MODLIST *mods, + char *name, size_t size, char *val) +{ + struct berval *bval = NULL; + + if (!(bval = talloc_zero(ctx, sizeof(struct berval *)))) + return ADS_ERROR(LDAP_NO_MEMORY); + + if (!val) + return ads_mod_add_ber(ctx, mods, LDAP_MOD_DELETE, name, NULL); + else { + if (!(bval->bv_val = talloc_zero(ctx, sizeof(char *)))) + return ADS_ERROR(LDAP_NO_MEMORY); + bval->bv_val = val; + bval->bv_len = size; + return ads_mod_add_ber(ctx, mods, LDAP_MOD_ADD, name, + bval, NULL); } } @@ -342,63 +372,16 @@ ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, ADS_MODLIST mods) return ADS_ERROR(ret); } -/* - a convenient routine for adding a generic LDAP record -*/ -ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ...) +ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ADS_MODLIST mods) { int i; - va_list ap; - LDAPMod **mods; - char *name, *value; - int ret; -#define MAX_MOD_VALUES 10 - - /* count the number of attributes */ - va_start(ap, new_dn); - for (i=0; va_arg(ap, char *); i++) { - /* skip the values */ - while (va_arg(ap, char *)) ; - } - va_end(ap); - if (!(mods = malloc(sizeof(LDAPMod *) * (i+1)))) - return ADS_ERROR(LDAP_NO_MEMORY); - - va_start(ap, new_dn); - for (i=0; (name=va_arg(ap, char *)); i++) { - char **values; - int j; - if (!(values = - (char **)malloc(sizeof(char *) * (MAX_MOD_VALUES+1)))) { - free(mods); - return ADS_ERROR(LDAP_NO_MEMORY); - } - for (j=0; (value=va_arg(ap, char *)) && j < MAX_MOD_VALUES; j++) { - values[j] = value; - } - values[j] = NULL; - if (!(mods[i] = malloc(sizeof(LDAPMod)))) { - free(values); - free(mods); - return ADS_ERROR(LDAP_NO_MEMORY); - } - mods[i]->mod_type = name; - mods[i]->mod_op = LDAP_MOD_ADD; - mods[i]->mod_values = values; - } + /* find the end of the list, marked by NULL or -1 */ + for(i=0;(mods[i]!=0)&&(mods[i]!=(LDAPMod *) -1);i++); + /* make sure the end of the list is NULL */ mods[i] = NULL; - va_end(ap); - - ret = ldap_add_s(ads->ld, new_dn, mods); - for (i=0; mods[i]; i++) { - free(mods[i]->mod_values); - free(mods[i]); - } - free(mods); - - return ADS_ERROR(ret); + return ADS_ERROR(ldap_add_s(ads->ld, new_dn, mods)); } ADS_STATUS ads_del_dn(ADS_STRUCT *ads, char *del_dn) @@ -432,37 +415,51 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, ADS_STATUS ret; char *host_spn, *host_upn, *new_dn, *samAccountName, *controlstr; char *ou_str; + TALLOC_CTX *ctx; + ADS_MODLIST mods; - asprintf(&host_spn, "HOST/%s", hostname); - asprintf(&host_upn, "%s@%s", host_spn, ads->realm); + if (!(ctx = talloc_init_named("machine_account"))) + return ADS_ERROR(LDAP_NO_MEMORY); + + ret = ADS_ERROR(LDAP_NO_MEMORY); + + if (!(host_spn = talloc_asprintf(ctx, "HOST/%s", hostname))) + goto done; + if (!(host_upn = talloc_asprintf(ctx, "%s@%s", host_spn, ads->realm))) + goto done; ou_str = ads_ou_string(org_unit); - asprintf(&new_dn, "cn=%s,%s,%s", hostname, ou_str, ads->bind_path); + new_dn = talloc_asprintf(ctx, "cn=%s,%s,%s", hostname, ou_str, + ads->bind_path); free(ou_str); - asprintf(&samAccountName, "%s$", hostname); - asprintf(&controlstr, "%u", - UF_DONT_EXPIRE_PASSWD | UF_WORKSTATION_TRUST_ACCOUNT | - UF_TRUSTED_FOR_DELEGATION | UF_USE_DES_KEY_ONLY); - - ret = ads_gen_add(ads, new_dn, - "cn", hostname, NULL, - "sAMAccountName", samAccountName, NULL, - "objectClass", - "top", "person", "organizationalPerson", - "user", "computer", NULL, - "userPrincipalName", host_upn, NULL, - "servicePrincipalName", host_spn, NULL, - "dNSHostName", hostname, NULL, - "userAccountControl", controlstr, NULL, - "operatingSystem", "Samba", NULL, - "operatingSystemVersion", VERSION, NULL, - NULL); - - free(host_spn); - free(host_upn); - free(new_dn); - free(samAccountName); - free(controlstr); - + if (!new_dn) + goto done; + + if (!(samAccountName = talloc_asprintf(ctx, "%s$", hostname))) + goto done; + if (!(controlstr = talloc_asprintf(ctx, "%u", + UF_DONT_EXPIRE_PASSWD | UF_WORKSTATION_TRUST_ACCOUNT | + UF_TRUSTED_FOR_DELEGATION | UF_USE_DES_KEY_ONLY))) + goto done; + + if (!(mods = ads_init_mods(ctx))) + goto done; + + ads_mod_add(ctx, &mods, "cn", hostname); + ads_mod_add(ctx, &mods, "sAMAccountName", samAccountName); + ads_mod_add_var(ctx, &mods, LDAP_MOD_ADD, "objectClass", + "top", "person", "organizationalPerson", + "user", "computer", NULL); + ads_mod_add(ctx, &mods, "userPrincipalName", host_upn); + ads_mod_add(ctx, &mods, "servicePrincipalName", host_spn); + ads_mod_add(ctx, &mods, "dNSHostName", hostname); + ads_mod_add(ctx, &mods, "userAccountControl", controlstr); + ads_mod_add(ctx, &mods, "operatingSystem", "Samba"); + ads_mod_add(ctx, &mods, "operatingSystemVersion", VERSION); + + ret = ads_gen_add(ads, new_dn, mods); + +done: + talloc_destroy(ctx); return ret; } -- cgit From d6b82723a0f626c52a3cf05d3bb4f0ff5f7e0f7a Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Tue, 12 Feb 2002 18:22:47 +0000 Subject: talloc'ify ads modify functions. (This used to be commit e097666499564ffe28836876a7a191149c14f199) --- source3/libads/ldap_printer.c | 86 +++++++++++++++++++++++++------------------ 1 file changed, 51 insertions(+), 35 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index 50f4302201..52771ba39a 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -45,7 +45,7 @@ ADS_STATUS ads_find_printer_on_server(ADS_STRUCT *ads, void **res, asprintf(&exp, "(printerName=%s)", printer); status = ads_do_search(ads, srv_dn, LDAP_SCOPE_SUBTREE, - exp, &attrs, res); + exp, attrs, res); free(exp); return status; @@ -57,46 +57,51 @@ ADS_STATUS ads_find_printer_on_server(ADS_STRUCT *ads, void **res, ADS_STATUS ads_mod_printer_entry(ADS_STRUCT *ads, char *prt_dn, const ADS_PRINTER_ENTRY *prt) { - ADS_MODLIST *mods; + ADS_MODLIST mods; ADS_STATUS status; + TALLOC_CTX *ctx; + + if (!(ctx = talloc_init_named("mod_printer_entry"))) + return ADS_ERROR(LDAP_NO_MEMORY); /* allocate the list */ - *mods = ads_init_mods(); + mods = ads_init_mods(ctx); /* add the attributes to the list - required ones first */ - ads_mod_repl(mods, "printerName", prt->printerName); - ads_mod_repl(mods, "serverName", prt->serverName); - ads_mod_repl(mods, "shortServerName", prt->shortServerName); - ads_mod_repl(mods, "uNCName", prt->uNCName); - ads_mod_repl(mods, "versionNumber", prt->versionNumber); + ads_mod_repl(ctx, &mods, "printerName", prt->printerName); + ads_mod_repl(ctx, &mods, "serverName", prt->serverName); + ads_mod_repl(ctx, &mods, "shortServerName", prt->shortServerName); + ads_mod_repl(ctx, &mods, "uNCName", prt->uNCName); + ads_mod_repl(ctx, &mods, "versionNumber", prt->versionNumber); /* now the optional ones */ - ads_mod_repl_list(mods, "description", prt->description); - ads_mod_repl(mods, "assetNumber",prt->assetNumber); - ads_mod_repl(mods, "bytesPerMinute",prt->bytesPerMinute); - ads_mod_repl(mods, "defaultPriority",prt->defaultPriority); - ads_mod_repl(mods, "driverName", prt->driverName); - ads_mod_repl(mods, "driverVersion",prt->driverVersion); - ads_mod_repl(mods, "location", prt->location); - ads_mod_repl(mods, "operatingSystem",prt->operatingSystem); - ads_mod_repl(mods, "operatingSystemHotfix",prt->operatingSystemHotfix); - ads_mod_repl(mods, "operatingSystemServicePack", + ads_mod_repl_list(ctx, &mods, "description", prt->description); + ads_mod_repl(ctx, &mods, "assetNumber",prt->assetNumber); + ads_mod_repl(ctx, &mods, "bytesPerMinute",prt->bytesPerMinute); + ads_mod_repl(ctx, &mods, "defaultPriority",prt->defaultPriority); + ads_mod_repl(ctx, &mods, "driverName", prt->driverName); + ads_mod_repl(ctx, &mods, "driverVersion",prt->driverVersion); + ads_mod_repl(ctx, &mods, "location", prt->location); + ads_mod_repl(ctx, &mods, "operatingSystem",prt->operatingSystem); + ads_mod_repl(ctx, &mods, "operatingSystemHotfix", + prt->operatingSystemHotfix); + ads_mod_repl(ctx, &mods, "operatingSystemServicePack", prt->operatingSystemServicePack); - ads_mod_repl(mods, "operatingSystemVersion", + ads_mod_repl(ctx, &mods, "operatingSystemVersion", prt->operatingSystemVersion); - ads_mod_repl(mods, "physicalLocationObject", + ads_mod_repl(ctx, &mods, "physicalLocationObject", prt->physicalLocationObject); - ads_mod_repl_list(mods, "portName", prt->portName); - ads_mod_repl(mods, "printStartTime", prt->printStartTime); - ads_mod_repl(mods, "printEndTime", prt->printEndTime); - ads_mod_repl_list(mods, "printBinNames", prt->printBinNames); + ads_mod_repl_list(ctx, &mods, "portName", prt->portName); + ads_mod_repl(ctx, &mods, "printStartTime", prt->printStartTime); + ads_mod_repl(ctx, &mods, "printEndTime", prt->printEndTime); + ads_mod_repl_list(ctx, &mods, "printBinNames", prt->printBinNames); /*... and many others */ /* do the ldap modify */ - status = ads_gen_mod(ads, prt_dn, *mods); + status = ads_gen_mod(ads, prt_dn, mods); /* free mod list, mods, and values */ - ads_free_mods(*mods); + talloc_destroy(ctx); return status; } @@ -109,16 +114,27 @@ static ADS_STATUS ads_add_printer_entry(ADS_STRUCT *ads, char *prt_dn, const ADS_PRINTER_ENTRY *prt) { ADS_STATUS status; - + TALLOC_CTX *ctx; + ADS_MODLIST mods; + + if (!(ctx = talloc_init_named("add_printer_entry"))) + return ADS_ERROR(LDAP_NO_MEMORY); + + if (!(mods = ads_init_mods(ctx))) + return ADS_ERROR(LDAP_NO_MEMORY); + /* These are the fields a printQueue must contain */ - status = ads_gen_add(ads, prt_dn, - "uNCName", prt->uNCName, NULL, - "versionNumber", prt->versionNumber, NULL, - "serverName", prt->serverName, NULL, - "shortServerName", prt->shortServerName, NULL, - "printerName", prt->printerName, NULL, - "objectClass", "printQueue", NULL, - NULL); + ads_mod_add(ctx, &mods, "uNCName", prt->uNCName); + ads_mod_add(ctx, &mods, "versionNumber", prt->versionNumber); + ads_mod_add(ctx, &mods, "serverName", prt->serverName); + ads_mod_add(ctx, &mods, "shortServerName", prt->shortServerName); + ads_mod_add(ctx, &mods, "printerName", prt->printerName); + ads_mod_add(ctx, &mods, "objectClass", "printQueue"); + + + status = ads_gen_add(ads, prt_dn, mods); + + talloc_destroy(ctx); return status; } -- cgit From 9fc99e3c552a6747a83877bda0410c951d272b81 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Wed, 13 Feb 2002 15:00:39 +0000 Subject: Fix LDAP modification operation. Cut and paste error: was LDAP_MOD_ADD, should be LDAP_MOD_REPLACE. Caught by Alexey Kotovich. (This used to be commit be48a05ed95f0f4ed02ffb996cb1ecc10811d9a0) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 682524eb4f..763f1bc354 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -343,7 +343,7 @@ ADS_STATUS ads_mod_repl_len(TALLOC_CTX *ctx, ADS_MODLIST *mods, return ADS_ERROR(LDAP_NO_MEMORY); bval->bv_val = val; bval->bv_len = size; - return ads_mod_add_ber(ctx, mods, LDAP_MOD_ADD, name, + return ads_mod_add_ber(ctx, mods, LDAP_MOD_REPLACE, name, bval, NULL); } } -- cgit From 23e6fc25e2ed11d09be127dd40f0f05fa4a94f3a Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Mon, 4 Mar 2002 01:07:02 +0000 Subject: fix for IRIX compile error (This used to be commit 2d620909f9def17dacf2af997a32d596f4dbd827) --- source3/libads/ldap.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 763f1bc354..ef1902960f 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -359,9 +359,10 @@ ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, ADS_MODLIST mods) "1.2.840.113556.1.4.1413", {0, NULL}, (char) 1}; - LDAPControl *controls[2] = { - &PermitModify, - NULL }; + LDAPControl *controls[2]; + + controls[0] = &PermitModify; + controls[1] = NULL; /* find the end of the list, marked by NULL or -1 */ for(i=0;(mods[i]!=0)&&(mods[i]!=(LDAPMod *) -1);i++); -- cgit From cfbbf736777aca366e388882a389a214b87ca612 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 10 Mar 2002 01:54:44 +0000 Subject: yipee! Finally put in the patch from Alexey Kotovich that adds the security decsriptor code for ADS workstation accounts thanks for your patience Cat, and thanks to Andrew Bartlett for extensive reviews and suggestions about this code. (This used to be commit 6891393b5db868246fe52ff62b3dc6aa5ca6f726) --- source3/libads/ldap.c | 129 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 121 insertions(+), 8 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index ef1902960f..a8f9298b0f 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -180,7 +180,7 @@ ADS_MODLIST ads_init_mods(TALLOC_CTX *ctx) add an attribute to the list, with values list already constructed */ static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, - int mod_op, char *name, char **values) + int mod_op, const char *name, char **values) { int curmod; LDAPMod **modlist = (LDAPMod **) *mods; @@ -238,7 +238,7 @@ ADS_STATUS ads_mod_repl_list(TALLOC_CTX *ctx, ADS_MODLIST *mods, add an attribute to the list, with values list to be built from args */ ADS_STATUS ads_mod_add_var(TALLOC_CTX *ctx, ADS_MODLIST *mods, - int mod_op, char *name, ...) + int mod_op, const char *name, ...) { va_list ap; int num_vals, i, do_op; @@ -267,7 +267,7 @@ ADS_STATUS ads_mod_add_var(TALLOC_CTX *ctx, ADS_MODLIST *mods, } ADS_STATUS ads_mod_add_ber(TALLOC_CTX *ctx, ADS_MODLIST *mods, - int mod_op, char *name, ...) + int mod_op, const char *name, ...) { va_list ap; int num_vals, i, do_op; @@ -308,7 +308,7 @@ ADS_STATUS ads_mod_repl(TALLOC_CTX *ctx, ADS_MODLIST *mods, } ADS_STATUS ads_mod_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, - char *name, char *val) + const char *name, const char *val) { return ads_mod_add_var(ctx, mods, LDAP_MOD_ADD, name, val, NULL); } @@ -329,7 +329,7 @@ ADS_STATUS ads_mod_add_len(TALLOC_CTX *ctx, ADS_MODLIST *mods, } ADS_STATUS ads_mod_repl_len(TALLOC_CTX *ctx, ADS_MODLIST *mods, - char *name, size_t size, char *val) + const char *name, size_t size, char *val) { struct berval *bval = NULL; @@ -457,7 +457,8 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, ads_mod_add(ctx, &mods, "operatingSystem", "Samba"); ads_mod_add(ctx, &mods, "operatingSystemVersion", VERSION); - ret = ads_gen_add(ads, new_dn, mods); + ads_gen_add(ads, new_dn, mods); + ret = ads_set_machine_sd(ads, hostname, new_dn); done: talloc_destroy(ctx); @@ -492,6 +493,36 @@ static void dump_sid(const char *field, struct berval **values) } } +/* + dump ntSecurityDescriptor +*/ +static void dump_sd(const char *filed, struct berval **values) +{ + prs_struct ps; + + SEC_DESC *psd = 0; + TALLOC_CTX *ctx = 0; + + if (!(ctx = talloc_init_named("sec_io_desc"))) + return; + + /* prepare data */ + prs_init(&ps, values[0]->bv_len, ctx, UNMARSHALL); + prs_append_data(&ps, values[0]->bv_val, values[0]->bv_len); + ps.data_offset = 0; + + /* parse secdesc */ + if (!sec_io_desc("sd", &psd, &ps, 1)) { + prs_mem_free(&ps); + talloc_destroy(ctx); + return; + } + if (psd) ads_disp_sd(psd); + + prs_mem_free(&ps); + talloc_destroy(ctx); +} + /* dump a string result from ldap */ @@ -517,7 +548,7 @@ void ads_dump(ADS_STRUCT *ads, void *res) void (*handler)(const char *, struct berval **); } handlers[] = { {"objectGUID", dump_binary}, - {"nTSecurityDescriptor", dump_binary}, + {"nTSecurityDescriptor", dump_sd}, {"objectSid", dump_sid}, {NULL, NULL} }; @@ -573,7 +604,7 @@ ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *hostname, const char *org status = ads_find_machine_acct(ads, (void **)&res, host); if (ADS_ERR_OK(status) && ads_count_replies(ads, res) == 1) { - DEBUG(0, ("Host account for %s already exists - deleting for readd\n", host)); + DEBUG(0, ("Host account for %s already exists - deleting old account\n", host)); status = ads_leave_realm(ads, host); if (!ADS_ERR_OK(status)) { DEBUG(0, ("Failed to delete host '%s' from the '%s' realm.\n", @@ -637,6 +668,83 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) return status; } +/* + add machine account to existing security descriptor +*/ +ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) +{ + const char *attrs[] = {"ntSecurityDescriptor", "objectSid", 0}; + char *exp = 0; + size_t sd_size = 0; + struct berval **bvals = 0; + prs_struct ps; + prs_struct ps_wire; + + LDAPMessage *res = 0; + LDAPMessage *msg = 0; + ADS_MODLIST mods = 0; + + NTSTATUS status; + ADS_STATUS ret; + DOM_SID sid; + SEC_DESC *psd = 0; + TALLOC_CTX *ctx = 0; + + if (!ads) return ADS_ERROR(LDAP_SERVER_DOWN); + + ret = ADS_ERROR(LDAP_SUCCESS); + + asprintf(&exp, "(samAccountName=%s$)", hostname); + ret = ads_search(ads, (void *) &res, exp, attrs); + + if (!ADS_ERR_OK(ret)) return ret; + + msg = ads_first_entry(ads, res); + bvals = ldap_get_values_len(ads->ld, msg, attrs[0]); + ads_pull_sid(ads, msg, attrs[1], &sid); + ads_msgfree(ads, res); +#if 0 + file_save("/tmp/sec_desc.old", bvals[0]->bv_val, bvals[0]->bv_len); +#endif + if (!(ctx = talloc_init_named("sec_io_desc"))) + return ADS_ERROR(LDAP_NO_MEMORY); + + prs_init(&ps, bvals[0]->bv_len, ctx, UNMARSHALL); + prs_append_data(&ps, bvals[0]->bv_val, bvals[0]->bv_len); + ps.data_offset = 0; + ldap_value_free_len(bvals); + + if (!sec_io_desc("sd", &psd, &ps, 1)) + goto ads_set_sd_error; + + status = sec_desc_add_sid(ctx, &psd, &sid, SEC_RIGHTS_FULL_CTRL, &sd_size); + + if (!NT_STATUS_IS_OK(status)) + goto ads_set_sd_error; + + prs_init(&ps_wire, sd_size, ctx, MARSHALL); + if (!sec_io_desc("sd_wire", &psd, &ps_wire, 1)) + goto ads_set_sd_error; + +#if 0 + file_save("/tmp/sec_desc.new", ps_wire.data_p, sd_size); +#endif + if (!(mods = ads_init_mods(ctx))) return ADS_ERROR(LDAP_NO_MEMORY); + + ads_mod_repl_len(ctx, &mods, attrs[0], sd_size, ps_wire.data_p); + ret = ads_gen_mod(ads, dn, mods); + + prs_mem_free(&ps); + prs_mem_free(&ps_wire); + talloc_destroy(ctx); + return ret; + +ads_set_sd_error: + prs_mem_free(&ps); + prs_mem_free(&ps_wire); + talloc_destroy(ctx); + return ADS_ERROR(LDAP_NO_MEMORY); +} ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads, const char *hostname, @@ -646,6 +754,11 @@ ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads, char *host = strdup(hostname); char *principal; + if (!ads->kdc_server) { + DEBUG(0, ("Unable to find KDC server\n")); + return ADS_ERROR(LDAP_SERVER_DOWN); + } + strlower(host); asprintf(&principal, "%s@%s", host, ads->realm); -- cgit From 1975b3e4a2318ca79aacae0f03dcbc68bdaeee45 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 10 Mar 2002 06:56:59 +0000 Subject: forgotten file, oops (This used to be commit 98196e79b733e029341578b382bdfabf3f9a0bdc) --- source3/libads/disp_sec.c | 175 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 source3/libads/disp_sec.c (limited to 'source3/libads') diff --git a/source3/libads/disp_sec.c b/source3/libads/disp_sec.c new file mode 100644 index 0000000000..c6fe0862c9 --- /dev/null +++ b/source3/libads/disp_sec.c @@ -0,0 +1,175 @@ +/* + Unix SMB/Netbios implementation. + Version 3.0. + Samba utility functions. ADS stuff + Copyright (C) Alexey Kotovich 2002 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +#ifdef HAVE_ADS + +static struct perm_mask_str { + uint32 mask; + char *str; +} perms[] = { + {SEC_RIGHTS_FULL_CTRL, "[Full Control]"}, + + {SEC_RIGHTS_LIST_CONTENTS, "[List Contents]"}, + {SEC_RIGHTS_LIST_OBJECT, "[List Object]"}, + + {SEC_RIGHTS_READ_ALL_PROP, "[Read All Properties]"}, + {SEC_RIGHTS_READ_PERMS, "[Read Permissions]"}, + + {SEC_RIGHTS_WRITE_ALL_VALID, "[All validate writes]"}, + {SEC_RIGHTS_WRITE_ALL_PROP, "[Write All Properties]"}, + + {SEC_RIGHTS_MODIFY_PERMS, "[Modify Permissions]"}, + {SEC_RIGHTS_MODIFY_OWNER, "[Modify Owner]"}, + + {SEC_RIGHTS_CREATE_CHILD, "[Create All Child Objects]"}, + + {SEC_RIGHTS_DELETE, "[Delete]"}, + {SEC_RIGHTS_DELETE_SUBTREE, "[Delete Subtree]"}, + {SEC_RIGHTS_DELETE_CHILD, "[Delete All Child Objects]"}, + + {SEC_RIGHTS_CHANGE_PASSWD, "[Change Password]"}, + {SEC_RIGHTS_RESET_PASSWD, "[Reset Password]"}, + {0, 0} +}; + +/* convert a security permissions into a string */ +void ads_disp_perms(uint32 type) +{ + int i = 0; + int j = 0; + + printf("Permissions: "); + + if (type == SEC_RIGHTS_FULL_CTRL) { + printf("%s\n", perms[j].str); + return; + } + + for (i = 0; i < 32; i++) { + if (type & (1 << i)) { + for (j = 1; perms[j].str; j ++) { + if (perms[j].mask == (((unsigned) 1) << i)) { + printf("\n\t%s", perms[j].str); + } + } + type &= ~(1 << i); + } + } + + /* remaining bits get added on as-is */ + if (type != 0) { + printf("[%08x]", type); + } + puts(""); +} + +/* Check if ACE has OBJECT type */ +BOOL ads_ace_object(uint8 type) +{ + if (type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT || + type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT || + type == SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT || + type == SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT) { + return True; + } + return False; +} + +/* display ACE */ +void ads_disp_ace(SEC_ACE *sec_ace) +{ + char *access_type = "UNKNOWN"; + + if (!sec_ace_object(sec_ace->type)) { + printf("------- ACE (type: 0x%02x, flags: 0x%02x, size: 0x%02x, mask: 0x%x)\n", + sec_ace->type, + sec_ace->flags, + sec_ace->size, + sec_ace->info.mask); + } else { + printf("------- ACE (type: 0x%02x, flags: 0x%02x, size: 0x%02x, mask: 0x%x, object flags: 0x%x)\n", + sec_ace->type, + sec_ace->flags, + sec_ace->size, + sec_ace->info.mask, + sec_ace->obj_flags); + } + + if (sec_ace->type == SEC_ACE_TYPE_ACCESS_ALLOWED) { + access_type = "ALLOWED"; + } else if (sec_ace->type == SEC_ACE_TYPE_ACCESS_DENIED) { + access_type = "DENIED"; + } else if (sec_ace->type == SEC_ACE_TYPE_SYSTEM_AUDIT) { + access_type = "SYSTEM AUDIT"; + } else if (sec_ace->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT) { + access_type = "ALLOWED OBJECT"; + } else if (sec_ace->type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT) { + access_type = "DEINED OBJECT"; + } else if (sec_ace->type == SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT) { + access_type = "AUDIT OBJECT"; + } + + printf("access SID: %s\naccess type: %s\n", + sid_string_static(&sec_ace->trustee), access_type); + + ads_disp_perms(sec_ace->info.mask); +} + +/* display ACL */ +void ads_disp_acl(SEC_ACL *sec_acl, char *type) +{ + if (!sec_acl) + printf("------- (%s) ACL not present\n", type); + else { + printf("------- (%s) ACL (revision: %d, size: %d, number of ACEs: %d)\n", + type, + sec_acl->revision, + sec_acl->size, + sec_acl->num_aces); + } +} + +/* display SD */ +void ads_disp_sd(SEC_DESC *sd) +{ + int i; + + printf("-------------- Security Descriptor (revision: %d, type: 0x%02x)\n", + sd->revision, + sd->type); + printf("owner SID: %s\n", sid_string_static(sd->owner_sid)); + printf("group SID: %s\n", sid_string_static(sd->grp_sid)); + + ads_disp_acl(sd->sacl, "system"); + for (i = 0; i < sd->sacl->num_aces; i ++) + ads_disp_ace(&sd->sacl->ace[i]); + + ads_disp_acl(sd->dacl, "user"); + for (i = 0; i < sd->dacl->num_aces; i ++) + ads_disp_ace(&sd->dacl->ace[i]); + + printf("-------------- End Of Security Descriptor\n"); +} + +#endif + -- cgit From bd3a6e6cc984e91621f06a52ddc87909d9d83abc Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 11 Mar 2002 04:06:30 +0000 Subject: put in the ADS DNS hack, but commented out (This used to be commit 3396a671c59e6afe70a22ce64e4a9381b1d6fef8) --- source3/libads/ldap.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index a8f9298b0f..aa6e7c0036 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -47,6 +47,17 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); +#if KRB5_DNS_HACK + /* this is a really nasty hack to avoid ADS DNS problems. It needs a patch + to MIT kerberos to work (tridge) */ + { + char *env; + asprintf(&env, "KRB5_KDC_ADDRESS_%s", ads->server_realm); + setenv(env, inet_ntoa(*interpret_addr2(ads->ldap_server)), 1); + free(env); + } +#endif + if (ads->password) { if ((code = ads_kinit_password(ads))) return ADS_ERROR_KRB5(code); -- cgit From 2001b83faa9f0438adda40ffe12fea4a3dc6a733 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 13 Mar 2002 06:43:52 +0000 Subject: detect SIZELIMIT_EXCEEDED in ldap queries and truncate the problem is, how the heck do we properly handle these? Jerry? It seems that the Win2000 ADS server only returns a max of 1000 records! (This used to be commit 93389647203395da0e894c2e57348081e755884a) --- source3/libads/ldap.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index aa6e7c0036..e53f6d87db 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -84,6 +84,10 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, bind_path, scope, exp, (char **) attrs, 0, NULL, NULL, &timeout, LDAP_NO_LIMIT, (LDAPMessage **)res); + if (rc == LDAP_SIZELIMIT_EXCEEDED) { + DEBUG(3,("Warning! sizelimit exceeded in ldap. Truncating.\n")); + rc = 0; + } return ADS_ERROR(rc); } /* -- cgit From 0640a5ceeb974f06dc29669bdbce75fcf7154439 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Thu, 14 Mar 2002 17:48:26 +0000 Subject: This adds the Paged Result Control to ads searching. The new function, ads_do_paged_search, is the same as ads_do_search, but it also contains a count of records returned in this page, and a cookie for resuming, to be passed back. The cookie must start off NULL, and when it returns as NULL, the search is done. (This used to be commit 9afba67f9a56699e34735e1e425f97b2464f2402) --- source3/libads/ldap.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index e53f6d87db..28970e8fa9 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -66,6 +66,83 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) return ads_sasl_bind(ads); } +/* Do a search with paged results. cookie must be null on the first + call, and then returned on each subsequent call. It will be null + again when the entire search is complete */ + +ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, + int scope, const char *exp, + const char **attrs, void **res, + int *count, void **cookie) +{ + int rc; +#define ADS_PAGE_CTL_OID "1.2.840.113556.1.4.319" + int version; + LDAPControl PagedResults; + BerElement *berelem = NULL; + struct berval *berval = NULL; + LDAPControl *controls[2]; + LDAPControl **rcontrols, *cur_control; + + *res = NULL; + + ldap_get_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); + + /* Paged results only available on ldap v3 or later, so check + version first before using, since at connect time we're + only v2. Not sure exactly why... */ + if (version < LDAP_VERSION3) + return ADS_ERROR(LDAP_NOT_SUPPORTED); + + berelem = ber_alloc_t(LBER_USE_DER); + if (cookie && *cookie) { + ber_printf(berelem, "{iO}", (ber_int_t) 256, *cookie); + ber_bvfree(*cookie); /* don't need it from last time */ + } else { + ber_printf(berelem, "{io}", (ber_int_t) 256, "", 0); + } + ber_flatten(berelem, &berval); + PagedResults.ldctl_oid = ADS_PAGE_CTL_OID; + PagedResults.ldctl_iscritical = (char) 1; + PagedResults.ldctl_value.bv_len = berval->bv_len; + PagedResults.ldctl_value.bv_val = berval->bv_val; + + controls[0] = &PagedResults; + controls[1] = NULL; + + *res = NULL; + + rc = ldap_search_ext_s(ads->ld, bind_path, scope, exp, + (char **) attrs, 0, controls, NULL, + NULL, LDAP_NO_LIMIT, + (LDAPMessage **)res); + ber_free(berelem, 1); + ber_bvfree(berval); + + rc = ldap_parse_result(ads->ld, *res, NULL, NULL, NULL, + NULL, &rcontrols, 0); + + for (cur_control=rcontrols[0]; cur_control; cur_control++) { + if (strcmp(ADS_PAGE_CTL_OID, cur_control->ldctl_oid) == 0) { + berelem = ber_init(&cur_control->ldctl_value); + ber_scanf(berelem,"{iO}", (ber_int_t *) count, + &berval); + /* the berval is the cookie, but must be freed when + it is all done */ + if (berval->bv_len) /* still more to do */ + *cookie=ber_bvdup(berval); + else + *cookie=NULL; + ber_bvfree(berval); + ber_free(berelem, 1); + break; + } + } + ldap_controls_free(rcontrols); + + return ADS_ERROR(rc); +} + /* do a search with a timeout */ @@ -84,10 +161,12 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, bind_path, scope, exp, (char **) attrs, 0, NULL, NULL, &timeout, LDAP_NO_LIMIT, (LDAPMessage **)res); + if (rc == LDAP_SIZELIMIT_EXCEEDED) { DEBUG(3,("Warning! sizelimit exceeded in ldap. Truncating.\n")); rc = 0; } + return ADS_ERROR(rc); } /* -- cgit From f464ceb109bc9bdc288e0219c4b83da15ba6f1fc Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 19 Mar 2002 12:58:38 +0000 Subject: fixed paged controls on my box. The problem seems to be incorrect referrals parsing in the openldap libs. By disabling referrals we get valid controls back and the cookies work. (This used to be commit 8bf487ddff240150d7a92aaa0f978dd30062c331) --- source3/libads/ldap.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 28970e8fa9..8d865dd113 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -66,6 +66,7 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) return ads_sasl_bind(ads); } + /* Do a search with paged results. cookie must be null on the first call, and then returned on each subsequent call. It will be null again when the entire search is complete */ @@ -96,10 +97,10 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, berelem = ber_alloc_t(LBER_USE_DER); if (cookie && *cookie) { - ber_printf(berelem, "{iO}", (ber_int_t) 256, *cookie); + ber_printf(berelem, "{iO}", (ber_int_t) 1000, *cookie); ber_bvfree(*cookie); /* don't need it from last time */ } else { - ber_printf(berelem, "{io}", (ber_int_t) 256, "", 0); + ber_printf(berelem, "{io}", (ber_int_t) 1000, "", 0); } ber_flatten(berelem, &berval); PagedResults.ldctl_oid = ADS_PAGE_CTL_OID; @@ -111,17 +112,33 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, controls[1] = NULL; *res = NULL; - + + /* we need to disable referrals as the openldap libs don't + seem to handle them correctly. They result in the result + record containing the server control being removed from the + result list (tridge) */ + ldap_set_option(ads->ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF); + rc = ldap_search_ext_s(ads->ld, bind_path, scope, exp, (char **) attrs, 0, controls, NULL, NULL, LDAP_NO_LIMIT, (LDAPMessage **)res); + + if (rc) { + DEBUG(3,("ldap_search_ext_s(%s) -> %s\n", exp, ldap_err2string(rc))); + return ADS_ERROR(rc); + } + ber_free(berelem, 1); ber_bvfree(berval); - + rc = ldap_parse_result(ads->ld, *res, NULL, NULL, NULL, NULL, &rcontrols, 0); + if (!rcontrols) { + return ADS_ERROR(rc); + } + for (cur_control=rcontrols[0]; cur_control; cur_control++) { if (strcmp(ADS_PAGE_CTL_OID, cur_control->ldctl_oid) == 0) { berelem = ber_init(&cur_control->ldctl_value); -- cgit From b462700e53df7fa64a4cd019054eae9e7f746aef Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 19 Mar 2002 22:14:53 +0000 Subject: added a ads_do_search_all() call, which is a more convenient interface to paged searches. This makes updating winbindd to used paged searches trivial. (This used to be commit 514c11b4e3fcc765a8087405333bd351c05c9e36) --- source3/libads/ldap.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 8d865dd113..c8661c2ebb 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -99,6 +99,7 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, if (cookie && *cookie) { ber_printf(berelem, "{iO}", (ber_int_t) 1000, *cookie); ber_bvfree(*cookie); /* don't need it from last time */ + *cookie = NULL; } else { ber_printf(berelem, "{io}", (ber_int_t) 1000, "", 0); } @@ -160,6 +161,47 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, return ADS_ERROR(rc); } + +/* + this uses ads_do_paged_search() to return all entries in a large + search. The interface is the same as ads_do_search(), which makes + it more convenient than the paged interface + */ +ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, + int scope, const char *exp, + const char **attrs, void **res) +{ + void *cookie = NULL; + int count = 0; + ADS_STATUS status; + + status = ads_do_paged_search(ads, bind_path, scope, exp, attrs, res, &count, &cookie); + + if (!ADS_ERR_OK(status)) return status; + + while (cookie) { + void *res2 = NULL; + ADS_STATUS status2; + LDAPMessage *msg, *next; + + status2 = ads_do_paged_search(ads, bind_path, scope, exp, attrs, &res2, &count, &cookie); + + if (!ADS_ERR_OK(status2)) break; + + /* this relies on the way that ldap_add_result_entry() works internally. I hope + that this works on all ldap libs, but I have only tested with openldap */ + for (msg = ads_first_entry(ads, res2); msg; msg = next) { + next = ads_next_entry(ads, msg); + ldap_add_result_entry((LDAPMessage **)res, msg); + } + + /* note that we do not free res2, as the memory is now + part of the main returned list */ + } + + return status; +} + /* do a search with a timeout */ -- cgit From ce236d1dbf2673e2ff921683554cee41fca33249 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 22 Mar 2002 06:24:38 +0000 Subject: Stomped on some header file version numbers that have crept back in. (This used to be commit e66bdf1229ba84f64c19e817e2c4081dbbf0bee8) --- source3/libads/disp_sec.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/disp_sec.c b/source3/libads/disp_sec.c index c6fe0862c9..ab8ceecb0c 100644 --- a/source3/libads/disp_sec.c +++ b/source3/libads/disp_sec.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 3.0. + Unix SMB/CIFS implementation. Samba utility functions. ADS stuff Copyright (C) Alexey Kotovich 2002 -- cgit From 1a06eeb6dae9b148a6e70470660e51a42def2399 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Wed, 27 Mar 2002 02:58:58 +0000 Subject: Add server control to prevent referrals in paged searches. This keeps the scope limited to the domain at hand, and also keeps the openldap libs happy, since they don't currently chase referrals and return server controls properly at the same time. (This used to be commit 2bebc8a391bd80bd0e5adbedb3757fb4279ec414) --- source3/libads/ldap.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index c8661c2ebb..92898bc4db 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -78,11 +78,13 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, { int rc; #define ADS_PAGE_CTL_OID "1.2.840.113556.1.4.319" +#define ADS_NO_REFERRALS_OID "1.2.840.113556.1.4.1339" int version; LDAPControl PagedResults; + LDAPControl NoReferrals; BerElement *berelem = NULL; struct berval *berval = NULL; - LDAPControl *controls[2]; + LDAPControl *controls[3]; LDAPControl **rcontrols, *cur_control; *res = NULL; @@ -105,19 +107,29 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, } ber_flatten(berelem, &berval); PagedResults.ldctl_oid = ADS_PAGE_CTL_OID; - PagedResults.ldctl_iscritical = (char) 1; + PagedResults.ldctl_iscritical = (char) 0; PagedResults.ldctl_value.bv_len = berval->bv_len; PagedResults.ldctl_value.bv_val = berval->bv_val; - - controls[0] = &PagedResults; - controls[1] = NULL; + + NoReferrals.ldctl_oid = ADS_NO_REFERRALS_OID; + NoReferrals.ldctl_iscritical = (char) 0; + NoReferrals.ldctl_value.bv_len = 0; + NoReferrals.ldctl_value.bv_val = ""; + + controls[0] = &NoReferrals; + controls[1] = &PagedResults; + controls[2] = NULL; *res = NULL; /* we need to disable referrals as the openldap libs don't seem to handle them correctly. They result in the result record containing the server control being removed from the - result list (tridge) */ + result list (tridge) + + leaving this in despite the control that says don't generate + referrals, in case the server doesn't support it (jmcd) + */ ldap_set_option(ads->ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF); rc = ldap_search_ext_s(ads->ld, bind_path, scope, exp, -- cgit From 90ada79bbf227afd18e585b203dc1b46166a1318 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Wed, 27 Mar 2002 03:09:50 +0000 Subject: Whoops, left the paged control not critical in the paged search...kind of defeats the purpose. (This used to be commit 71806c49b366faf2466eee7352c71fcdfefd8cc1) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 92898bc4db..431c32a35c 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -107,7 +107,7 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, } ber_flatten(berelem, &berval); PagedResults.ldctl_oid = ADS_PAGE_CTL_OID; - PagedResults.ldctl_iscritical = (char) 0; + PagedResults.ldctl_iscritical = (char) 1; PagedResults.ldctl_value.bv_len = berval->bv_len; PagedResults.ldctl_value.bv_val = berval->bv_val; -- cgit From 2ed1dfcf4e467a2816f3b768c8b37f2cdf3c7758 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 29 Mar 2002 21:06:33 +0000 Subject: Added ads_process_results(), which takes a function that is called for each entry returned from a search, and applies it to the results. Re-structured ads_dump to use this, plus changed the ber_free in ads_dump from (b,1) to (b,0), in accordance with openldap manpages. Also allows proper free of result using ldap_msgfree afterwards, so you can do something with the results after an ads_dump. (This used to be commit f01f02fc569b4f5101a37d3b493f2fe2d2b2677a) --- source3/libads/ldap.c | 93 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 73 insertions(+), 20 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 431c32a35c..9670327dbe 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -700,14 +700,12 @@ static void dump_string(const char *field, struct berval **values) } /* - dump a record from LDAP on stdout + dump a field from LDAP on stdout used for debugging */ -void ads_dump(ADS_STRUCT *ads, void *res) + +static void ads_dump_field(char *field, void **values, void *data_area) { - char *field; - void *msg; - BerElement *b; struct { char *name; void (*handler)(const char *, struct berval **); @@ -717,34 +715,89 @@ void ads_dump(ADS_STRUCT *ads, void *res) {"objectSid", dump_sid}, {NULL, NULL} }; - - for (msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) { + int i; + + if (!field) { /* must be end of an entry */ + printf("\n"); + return; + } + + for (i=0; handlers[i].name; i++) { + if (StrCaseCmp(handlers[i].name, field) == 0) { + handlers[i].handler(field, (struct berval **) values); + break; + } + } + if (!handlers[i].name) { + dump_string(field, (struct berval **) values); + } +} + +/* + dump a result from LDAP on stdout + used for debugging +*/ + +void ads_dump(ADS_STRUCT *ads, void *res) +{ + ads_process_results(ads, res, ads_dump_field, NULL); +} + +/* + Walk through results, calling a function for each entry found. + The function receives a field name, a berval * array of values, + and a data area passed through from the start. The function is + called once with null for field and values at the end of each + entry. +*/ +void ads_process_results(ADS_STRUCT *ads, void *res, + void(*fn)(char *, void **, void *), + void *data_area) +{ + void *msg; + + for (msg = ads_first_entry(ads, res); msg; + msg = ads_next_entry(ads, msg)) { + char *field; + BerElement *b; + for (field = ldap_first_attribute(ads->ld, (LDAPMessage *)msg, &b); field; field = ldap_next_attribute(ads->ld, (LDAPMessage *)msg, b)) { struct berval **values; - int i; - + values = ldap_get_values_len(ads->ld, (LDAPMessage *)msg, field); + fn(field, (void **) values, data_area); - for (i=0; handlers[i].name; i++) { - if (StrCaseCmp(handlers[i].name, field) == 0) { - handlers[i].handler(field, values); - break; - } - } - if (!handlers[i].name) { - dump_string(field, values); - } ldap_value_free_len(values); ldap_memfree(field); } + ber_free(b, 0); + fn(NULL, NULL, data_area); /* completed an entry */ - ber_free(b, 1); - printf("\n"); } } +void ads_process_entry(ADS_STRUCT *ads, void *msg, + void(*fn)(ADS_STRUCT *, char *, void **, void *), + void *data_area) +{ + char *field; + BerElement *b; + + for (field = ldap_first_attribute(ads->ld, (LDAPMessage *)msg, &b); + field; + field = ldap_next_attribute(ads->ld, (LDAPMessage *)msg, b)) { + struct berval **values; + + values = ldap_get_values_len(ads->ld, (LDAPMessage *)msg, field); + fn(ads, field, (void **) values, data_area); + + ldap_value_free_len(values); + ldap_memfree(field); + } + ber_free(b, 0); +} /* count how many replies are in a LDAPMessage */ -- cgit From 417b1ce487c1db77c389587f9c187dc107d3dce4 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Thu, 4 Apr 2002 02:49:30 +0000 Subject: Add ads_err2string() function for generating error strings from an ADS_STATUS. I've got the cases besides gssapi...anyone know how to get those? (This used to be commit c937e1352207ad90e8257ad6c9f8b7c9cf92030d) --- source3/libads/ldap.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 9670327dbe..57fd3305e7 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -66,6 +66,21 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) return ads_sasl_bind(ads); } +char *ads_err2string(ADS_STATUS status) +{ + switch(status.error_type) { + case ADS_ERROR_LDAP: + return ldap_err2string(status.rc); + case ADS_ERROR_KRB5: + return error_message(status.rc); + case ADS_ERROR_GSS: + return "gssapi error"; + case ADS_ERROR_SYSTEM: + return strerror(status.rc); + default: + return "unknown error"; + } +} /* Do a search with paged results. cookie must be null on the first call, and then returned on each subsequent call. It will be null -- cgit From 3f31475eebb0d8eae3d9be58e23fc0e7200e2f96 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Thu, 4 Apr 2002 02:51:02 +0000 Subject: Contains functions to manage/view AD user accounts via ldap. Initially has fns to find and add a user. (This used to be commit 773303a284825af89d70ea633004fc30225e7a85) --- source3/libads/ldap_user.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 source3/libads/ldap_user.c (limited to 'source3/libads') diff --git a/source3/libads/ldap_user.c b/source3/libads/ldap_user.c new file mode 100644 index 0000000000..13e68eb82e --- /dev/null +++ b/source3/libads/ldap_user.c @@ -0,0 +1,80 @@ +/* + Unix SMB/CIFS implementation. + ads (active directory) utility library + Copyright (C) Jim McDonough 2002 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +#ifdef HAVE_ADS + +/* + find a user account +*/ +ADS_STATUS ads_find_user_acct(ADS_STRUCT *ads, void **res, const char *user) +{ + ADS_STATUS status; + char *exp; + const char *attrs[] = {"*", NULL}; + + asprintf(&exp, "(samAccountName=%s)", user); + status = ads_search(ads, res, exp, attrs); + free(exp); + return status; +} + +ADS_STATUS ads_add_user_acct(ADS_STRUCT *ads, const char *user, + const char *fullname) +{ + TALLOC_CTX *ctx; + ADS_MODLIST mods; + ADS_STATUS status; + char *upn, *new_dn, *name, *controlstr; + + if (fullname && *fullname) name = fullname; + else name = user; + + if (!(ctx = talloc_init_named("ads_add_user_acct"))) + return ADS_ERROR(LDAP_NO_MEMORY); + + status = ADS_ERROR(LDAP_NO_MEMORY); + + if (!(upn = talloc_asprintf(ctx, "%s@%s", user, ads->realm))) + goto done; + if (!(new_dn = talloc_asprintf(ctx, "cn=%s,cn=Users,%s", name, + ads->bind_path))) + goto done; + if (!(controlstr = talloc_asprintf(ctx, "%u", UF_NORMAL_ACCOUNT))) + goto done; + if (!(mods = ads_init_mods(ctx))) + goto done; + + ads_mod_add(ctx, &mods, "cn", name); + ads_mod_add_var(ctx, &mods, LDAP_MOD_ADD, "objectClass", "top", + "person", "organizationalPerson", "user", NULL); + ads_mod_add(ctx, &mods, "userPrincipalName", upn); + ads_mod_add(ctx, &mods, "name", name); + ads_mod_add(ctx, &mods, "displayName", name); + ads_mod_add(ctx, &mods, "sAMAccountName", user); + ads_mod_add(ctx, &mods, "userAccountControl", controlstr); + status = ads_gen_add(ads, new_dn, mods); + + done: + talloc_destroy(ctx); + return status; +} +#endif -- cgit From f21ccff91fe9dd37a57c6505fc19b7fc2c103a59 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Thu, 4 Apr 2002 03:03:00 +0000 Subject: Try harder next time to not duplicate function...take ads_err2string back out since it's already in ads_errstr() in ads_status.c (This used to be commit 0475126ffb69f0485fd31511cb13d98df74a8d5b) --- source3/libads/ldap.c | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 57fd3305e7..9670327dbe 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -66,21 +66,6 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) return ads_sasl_bind(ads); } -char *ads_err2string(ADS_STATUS status) -{ - switch(status.error_type) { - case ADS_ERROR_LDAP: - return ldap_err2string(status.rc); - case ADS_ERROR_KRB5: - return error_message(status.rc); - case ADS_ERROR_GSS: - return "gssapi error"; - case ADS_ERROR_SYSTEM: - return strerror(status.rc); - default: - return "unknown error"; - } -} /* Do a search with paged results. cookie must be null on the first call, and then returned on each subsequent call. It will be null -- cgit From 40260fdaf906d7f4d71a461f294e3c99b564d13c Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 5 Apr 2002 19:26:52 +0000 Subject: Several updates to get server side sorting going: - Added sort control to ads_do_paged_search. It allows a char * to be passed as the sort key. If NULL, no sort is done. - fixed a bug in the processing of controls (loop wasn't incremented properly) - Added ads_do_search_all2, which funs a function that is passed in against each entry. No ldapmessage structures are returned. Allows results to be processed as the come in on each page. I'd like ads_do_search_all2 to replace ads_do_search_all, but there's some work to be done in winbindd_ads.c first. Also, perhaps now we can do async ldap searches? Allow us to process a page while the server retrieves the next one? (This used to be commit 95bec4c8bae0e29f816ec0751bf66404e1f2098e) --- source3/libads/ldap.c | 104 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 78 insertions(+), 26 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 9670327dbe..82b7d7568c 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -74,18 +74,21 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, int scope, const char *exp, const char **attrs, void **res, - int *count, void **cookie) + int *count, void **cookie, const char *sort) { int rc; #define ADS_PAGE_CTL_OID "1.2.840.113556.1.4.319" #define ADS_NO_REFERRALS_OID "1.2.840.113556.1.4.1339" +#define ADS_SERVER_SORT_OID "1.2.840.113556.1.4.473" int version; LDAPControl PagedResults; LDAPControl NoReferrals; - BerElement *berelem = NULL; - struct berval *berval = NULL; - LDAPControl *controls[3]; - LDAPControl **rcontrols, *cur_control; + LDAPControl ServerSort; + BerElement *cookie_be = NULL, *sort_be = NULL; + struct berval *cookie_bv= NULL, *sort_bv = NULL; + LDAPControl *controls[4]; + LDAPControl **rcontrols; + int i; *res = NULL; @@ -97,28 +100,39 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, if (version < LDAP_VERSION3) return ADS_ERROR(LDAP_NOT_SUPPORTED); - berelem = ber_alloc_t(LBER_USE_DER); + cookie_be = ber_alloc_t(LBER_USE_DER); if (cookie && *cookie) { - ber_printf(berelem, "{iO}", (ber_int_t) 1000, *cookie); + ber_printf(cookie_be, "{iO}", (ber_int_t) 1000, *cookie); ber_bvfree(*cookie); /* don't need it from last time */ *cookie = NULL; } else { - ber_printf(berelem, "{io}", (ber_int_t) 1000, "", 0); + ber_printf(cookie_be, "{io}", (ber_int_t) 1000, "", 0); } - ber_flatten(berelem, &berval); + ber_flatten(cookie_be, &cookie_bv); PagedResults.ldctl_oid = ADS_PAGE_CTL_OID; PagedResults.ldctl_iscritical = (char) 1; - PagedResults.ldctl_value.bv_len = berval->bv_len; - PagedResults.ldctl_value.bv_val = berval->bv_val; + PagedResults.ldctl_value.bv_len = cookie_bv->bv_len; + PagedResults.ldctl_value.bv_val = cookie_bv->bv_val; NoReferrals.ldctl_oid = ADS_NO_REFERRALS_OID; NoReferrals.ldctl_iscritical = (char) 0; NoReferrals.ldctl_value.bv_len = 0; NoReferrals.ldctl_value.bv_val = ""; + if (sort && *sort) { + sort_be = ber_alloc_t(LBER_USE_DER); + ber_printf(sort_be, "{{s}}", sort); + ber_flatten(sort_be, &sort_bv); + ServerSort.ldctl_oid = ADS_SERVER_SORT_OID; + ServerSort.ldctl_iscritical = (char) 0; + ServerSort.ldctl_value.bv_len = sort_bv->bv_len; + ServerSort.ldctl_value.bv_val = sort_bv->bv_val; + } + controls[0] = &NoReferrals; controls[1] = &PagedResults; - controls[2] = NULL; + controls[2] = (sort && *sort) ? &ServerSort : NULL; + controls[3] = NULL; *res = NULL; @@ -137,14 +151,18 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, NULL, LDAP_NO_LIMIT, (LDAPMessage **)res); + ber_free(cookie_be, 1); + ber_bvfree(cookie_bv); + if (sort && *sort) { + ber_free(sort_be, 1); + ber_bvfree(sort_bv); + } + if (rc) { DEBUG(3,("ldap_search_ext_s(%s) -> %s\n", exp, ldap_err2string(rc))); return ADS_ERROR(rc); } - ber_free(berelem, 1); - ber_bvfree(berval); - rc = ldap_parse_result(ads->ld, *res, NULL, NULL, NULL, NULL, &rcontrols, 0); @@ -152,19 +170,19 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, return ADS_ERROR(rc); } - for (cur_control=rcontrols[0]; cur_control; cur_control++) { - if (strcmp(ADS_PAGE_CTL_OID, cur_control->ldctl_oid) == 0) { - berelem = ber_init(&cur_control->ldctl_value); - ber_scanf(berelem,"{iO}", (ber_int_t *) count, - &berval); + for (i=0; rcontrols[i]; i++) { + if (strcmp(ADS_PAGE_CTL_OID, rcontrols[i]->ldctl_oid) == 0) { + cookie_be = ber_init(&rcontrols[i]->ldctl_value); + ber_scanf(cookie_be,"{iO}", (ber_int_t *) count, + &cookie_bv); /* the berval is the cookie, but must be freed when it is all done */ - if (berval->bv_len) /* still more to do */ - *cookie=ber_bvdup(berval); + if (cookie_bv->bv_len) /* still more to do */ + *cookie=ber_bvdup(cookie_bv); else *cookie=NULL; - ber_bvfree(berval); - ber_free(berelem, 1); + ber_bvfree(cookie_bv); + ber_free(cookie_be, 1); break; } } @@ -187,7 +205,7 @@ ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, int count = 0; ADS_STATUS status; - status = ads_do_paged_search(ads, bind_path, scope, exp, attrs, res, &count, &cookie); + status = ads_do_paged_search(ads, bind_path, scope, exp, attrs, res, &count, &cookie, NULL); if (!ADS_ERR_OK(status)) return status; @@ -196,7 +214,7 @@ ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, ADS_STATUS status2; LDAPMessage *msg, *next; - status2 = ads_do_paged_search(ads, bind_path, scope, exp, attrs, &res2, &count, &cookie); + status2 = ads_do_paged_search(ads, bind_path, scope, exp, attrs, &res2, &count, &cookie, NULL); if (!ADS_ERR_OK(status2)) break; @@ -214,6 +232,40 @@ ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, return status; } +/* same as ads_do_search_all, but runs a function on each result, rather + than returning it. Needed to get sorting working, as the merging of + ads_do_search_all messes it up. This should eventually replace it. */ + +ADS_STATUS ads_do_search_all2(ADS_STRUCT *ads, const char *bind_path, + int scope, const char *exp, + const char **attrs, const char *sort, + void(*fn)(char *, void **, void *), + void *data_area) +{ + void *cookie = NULL; + int count = 0; + ADS_STATUS status; + void *res; + + status = ads_do_paged_search(ads, bind_path, scope, exp, attrs, &res, &count, &cookie, sort); + + if (!ADS_ERR_OK(status)) return status; + + ads_process_results(ads, res, fn, data_area); + ads_msgfree(ads, res); + + while (cookie) { + status = ads_do_paged_search(ads, bind_path, scope, exp, attrs, &res, &count, &cookie, NULL); + + if (!ADS_ERR_OK(status)) break; + + ads_process_results(ads, res, fn, data_area); + ads_msgfree(ads, res); + } + + return status; +} + /* do a search with a timeout */ -- cgit From 69f41523b39f0bf487b719da2905793a5bd292ee Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Wed, 10 Apr 2002 13:28:03 +0000 Subject: A few more updates: - Add doxygen comments - remove server sort control (ms implementation was not reliable) - rename ads_do_search_all2() to ads_do_search_all_fn() (This used to be commit 7aa5fa617221019de0f4565d07842df72673e154) --- source3/libads/ldap.c | 480 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 348 insertions(+), 132 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 82b7d7568c..e2e351bd4b 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -24,9 +24,19 @@ #ifdef HAVE_ADS -/* - connect to the LDAP server -*/ +/** + * @file ldap.c + * @brief basic ldap client-side routines for ads server communications + * + * The routines contained here should do the necessary ldap calls for + * ads setups. + **/ + +/** + * Connect to the LDAP server + * @param ads Pointer to an existing ADS_STRUCT + * @return status of connection + **/ ADS_STATUS ads_connect(ADS_STRUCT *ads) { int version = LDAP_VERSION3; @@ -67,26 +77,32 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) } -/* Do a search with paged results. cookie must be null on the first - call, and then returned on each subsequent call. It will be null - again when the entire search is complete */ - +/** + * Do a search with paged results. cookie must be null on the first + * call, and then returned on each subsequent call. It will be null + * again when the entire search is complete + * @param ads connection to ads server + * @param bind_path Base dn for the search + * @param scope Scope of search (LDAP_BASE | LDAP_ONE | LDAP_SUBTREE) + * @param exp Search expression + * @param attrs Attributes to retrieve + * @param res ** which will contain results - free res* with ads_msgfree() + * @param count Number of entries retrieved on this page + * @param cookie The paged results cookie to be returned on subsequent calls + * @return status of search + **/ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, int scope, const char *exp, const char **attrs, void **res, - int *count, void **cookie, const char *sort) + int *count, void **cookie) { int rc; -#define ADS_PAGE_CTL_OID "1.2.840.113556.1.4.319" -#define ADS_NO_REFERRALS_OID "1.2.840.113556.1.4.1339" -#define ADS_SERVER_SORT_OID "1.2.840.113556.1.4.473" int version; LDAPControl PagedResults; LDAPControl NoReferrals; - LDAPControl ServerSort; - BerElement *cookie_be = NULL, *sort_be = NULL; - struct berval *cookie_bv= NULL, *sort_bv = NULL; - LDAPControl *controls[4]; + BerElement *cookie_be = NULL; + struct berval *cookie_bv= NULL; + LDAPControl *controls[3]; LDAPControl **rcontrols; int i; @@ -119,20 +135,10 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, NoReferrals.ldctl_value.bv_len = 0; NoReferrals.ldctl_value.bv_val = ""; - if (sort && *sort) { - sort_be = ber_alloc_t(LBER_USE_DER); - ber_printf(sort_be, "{{s}}", sort); - ber_flatten(sort_be, &sort_bv); - ServerSort.ldctl_oid = ADS_SERVER_SORT_OID; - ServerSort.ldctl_iscritical = (char) 0; - ServerSort.ldctl_value.bv_len = sort_bv->bv_len; - ServerSort.ldctl_value.bv_val = sort_bv->bv_val; - } controls[0] = &NoReferrals; controls[1] = &PagedResults; - controls[2] = (sort && *sort) ? &ServerSort : NULL; - controls[3] = NULL; + controls[2] = NULL; *res = NULL; @@ -153,10 +159,6 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, ber_free(cookie_be, 1); ber_bvfree(cookie_bv); - if (sort && *sort) { - ber_free(sort_be, 1); - ber_bvfree(sort_bv); - } if (rc) { DEBUG(3,("ldap_search_ext_s(%s) -> %s\n", exp, ldap_err2string(rc))); @@ -192,11 +194,17 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, } -/* - this uses ads_do_paged_search() to return all entries in a large - search. The interface is the same as ads_do_search(), which makes - it more convenient than the paged interface - */ +/** + * Get all results for a search. This uses ads_do_paged_search() to return + * all entries in a large search. + * @param ads connection to ads server + * @param bind_path Base dn for the search + * @param scope Scope of search (LDAP_BASE | LDAP_ONE | LDAP_SUBTREE) + * @param exp Search expression + * @param attrs Attributes to retrieve + * @param res ** which will contain results - free res* with ads_msgfree() + * @return status of search + **/ ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, int scope, const char *exp, const char **attrs, void **res) @@ -205,7 +213,8 @@ ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, int count = 0; ADS_STATUS status; - status = ads_do_paged_search(ads, bind_path, scope, exp, attrs, res, &count, &cookie, NULL); + status = ads_do_paged_search(ads, bind_path, scope, exp, attrs, res, + &count, &cookie); if (!ADS_ERR_OK(status)) return status; @@ -214,7 +223,8 @@ ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, ADS_STATUS status2; LDAPMessage *msg, *next; - status2 = ads_do_paged_search(ads, bind_path, scope, exp, attrs, &res2, &count, &cookie, NULL); + status2 = ads_do_paged_search(ads, bind_path, scope, exp, + attrs, &res2, &count, &cookie); if (!ADS_ERR_OK(status2)) break; @@ -232,22 +242,30 @@ ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, return status; } -/* same as ads_do_search_all, but runs a function on each result, rather - than returning it. Needed to get sorting working, as the merging of - ads_do_search_all messes it up. This should eventually replace it. */ - -ADS_STATUS ads_do_search_all2(ADS_STRUCT *ads, const char *bind_path, - int scope, const char *exp, - const char **attrs, const char *sort, - void(*fn)(char *, void **, void *), - void *data_area) +/** + * Run a function on all results for a search. Uses ads_do_paged_search() and + * runs the function as each page is returned, using ads_process_results() + * @param ads connection to ads server + * @param bind_path Base dn for the search + * @param scope Scope of search (LDAP_BASE | LDAP_ONE | LDAP_SUBTREE) + * @param exp Search expression + * @param attrs Attributes to retrieve + * @param fn Function which takes attr name, values list, and data_area + * @param data_area Pointer which is passed to function on each call + * @return status of search + **/ +ADS_STATUS ads_do_search_all_fn(ADS_STRUCT *ads, const char *bind_path, + int scope, const char *exp, const char **attrs, + void(*fn)(char *, void **, void *), + void *data_area) { void *cookie = NULL; int count = 0; ADS_STATUS status; void *res; - status = ads_do_paged_search(ads, bind_path, scope, exp, attrs, &res, &count, &cookie, sort); + status = ads_do_paged_search(ads, bind_path, scope, exp, attrs, &res, + &count, &cookie); if (!ADS_ERR_OK(status)) return status; @@ -255,7 +273,8 @@ ADS_STATUS ads_do_search_all2(ADS_STRUCT *ads, const char *bind_path, ads_msgfree(ads, res); while (cookie) { - status = ads_do_paged_search(ads, bind_path, scope, exp, attrs, &res, &count, &cookie, NULL); + status = ads_do_paged_search(ads, bind_path, scope, exp, attrs, + &res, &count, &cookie); if (!ADS_ERR_OK(status)) break; @@ -266,9 +285,16 @@ ADS_STATUS ads_do_search_all2(ADS_STRUCT *ads, const char *bind_path, return status; } -/* - do a search with a timeout -*/ +/** + * Do a search with a timeout. + * @param ads connection to ads server + * @param bind_path Base dn for the search + * @param scope Scope of search (LDAP_BASE | LDAP_ONE | LDAP_SUBTREE) + * @param exp Search expression + * @param attrs Attributes to retrieve + * @param res ** which will contain results - free res* with ads_msgfree() + * @return status of search + **/ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, const char *exp, const char **attrs, void **res) @@ -292,9 +318,14 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, return ADS_ERROR(rc); } -/* - do a general ADS search -*/ +/** + * Do a general ADS search + * @param ads connection to ads server + * @param res ** which will contain results - free res* with ads_msgfree() + * @param exp Search expression + * @param attrs Attributes to retrieve + * @return status of search + **/ ADS_STATUS ads_search(ADS_STRUCT *ads, void **res, const char *exp, const char **attrs) @@ -303,9 +334,14 @@ ADS_STATUS ads_search(ADS_STRUCT *ads, void **res, exp, attrs, res); } -/* - do a search on a specific DistinguishedName -*/ +/** + * Do a search on a specific DistinguishedName + * @param ads connection to ads server + * @param res ** which will contain results - free res* with ads_msgfree() + * @param dn DistinguishName to search + * @param attrs Attributes to retrieve + * @return status of search + **/ ADS_STATUS ads_search_dn(ADS_STRUCT *ads, void **res, const char *dn, const char **attrs) @@ -313,35 +349,46 @@ ADS_STATUS ads_search_dn(ADS_STRUCT *ads, void **res, return ads_do_search(ads, dn, LDAP_SCOPE_BASE, "(objectclass=*)", attrs, res); } -/* - free up memory from a ads_search -*/ +/** + * Free up memory from a ads_search + * @param ads connection to ads server + * @param msg Search results to free + **/ void ads_msgfree(ADS_STRUCT *ads, void *msg) { if (!msg) return; ldap_msgfree(msg); } -/* - free up memory from various ads requests -*/ +/** + * Free up memory from various ads requests + * @param ads connection to ads server + * @param mem Area to free + **/ void ads_memfree(ADS_STRUCT *ads, void *mem) { if (!mem) return; ldap_memfree(mem); } -/* - get a dn from search results -*/ +/** + * Get a dn from search results + * @param ads connection to ads server + * @param res Search results + * @return dn string + **/ char *ads_get_dn(ADS_STRUCT *ads, void *res) { return ldap_get_dn(ads->ld, res); } -/* - find a machine account given a hostname -*/ +/** + * Find a machine account given a hostname + * @param ads connection to ads server + * @param res ** which will contain results - free res* with ads_msgfree() + * @param host Hostname to search for + * @return status of search + **/ ADS_STATUS ads_find_machine_acct(ADS_STRUCT *ads, void **res, const char *host) { ADS_STATUS status; @@ -375,10 +422,11 @@ static char **ads_dup_values(TALLOC_CTX *ctx, char **values) return newvals; } -/* - initialize a list of mods -*/ - +/** + * Initialize a list of mods to be used in a modify request + * @param ctx An initialized TALLOC_CTX + * @return allocated ADS_MODLIST + **/ ADS_MODLIST ads_init_mods(TALLOC_CTX *ctx) { #define ADS_MODLIST_ALLOC_SIZE 10 @@ -426,6 +474,14 @@ static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, return ADS_ERROR(LDAP_SUCCESS); } +/** + * Add an already-constructed list of values to a mod list for an ADD + * @param ctx An initialized TALLOC_CTX + * @param mods An initialized ADS_MODLIST + * @param name The attribute name to add + * @param values Constructed values list to add + * @return ADS STATUS indicating success of add + **/ ADS_STATUS ads_mod_add_list(TALLOC_CTX *ctx, ADS_MODLIST *mods, char *name, char **values) { @@ -436,6 +492,14 @@ ADS_STATUS ads_mod_add_list(TALLOC_CTX *ctx, ADS_MODLIST *mods, return ADS_ERROR(LDAP_NO_MEMORY); } +/** + * Add an already-constructed list of values to a mod list for a REPLACE + * @param ctx An initialized TALLOC_CTX + * @param mods An initialized ADS_MODLIST + * @param name The attribute name to add + * @param values Constructed values list to add + * @return ADS STATUS indicating success of add + **/ ADS_STATUS ads_mod_repl_list(TALLOC_CTX *ctx, ADS_MODLIST *mods, char *name, char **values) { @@ -451,9 +515,15 @@ ADS_STATUS ads_mod_repl_list(TALLOC_CTX *ctx, ADS_MODLIST *mods, return ads_modlist_add(ctx, mods, LDAP_MOD_DELETE, name, NULL); } -/* - add an attribute to the list, with values list to be built from args -*/ +/** + * Add any number of string values to a mod list - for ADD or REPLACE + * @param ctx An initialized TALLOC_CTX + * @param mods An initialized ADS_MODLIST + * @param mod_op Operation to perform (LDAP_MOD_ADD | LDAP_MOD_REPLACE) + * @param name The attribute name to add + * @param ... Any number of values, in (char *) form + * @return ADS STATUS indicating success of add + **/ ADS_STATUS ads_mod_add_var(TALLOC_CTX *ctx, ADS_MODLIST *mods, int mod_op, const char *name, ...) { @@ -483,6 +553,15 @@ ADS_STATUS ads_mod_add_var(TALLOC_CTX *ctx, ADS_MODLIST *mods, return ads_modlist_add(ctx, mods, do_op, name, values); } +/** + * Add any number of ber values to a mod list - for ADD or REPLACE + * @param ctx An initialized TALLOC_CTX + * @param mods An initialized ADS_MODLIST + * @param mod_op Operation to perform (LDAP_MOD_ADD | LDAP_MOD_REPLACE) + * @param name The attribute name to add + * @param ... Any number of values, in (struct berval *) form + * @return ADS STATUS indicating success of add + **/ ADS_STATUS ads_mod_add_ber(TALLOC_CTX *ctx, ADS_MODLIST *mods, int mod_op, const char *name, ...) { @@ -514,6 +593,14 @@ ADS_STATUS ads_mod_add_ber(TALLOC_CTX *ctx, ADS_MODLIST *mods, return ads_modlist_add(ctx, mods, do_op, name, values); } +/** + * Add a single string value to a mod list - for REPLACE + * @param ctx An initialized TALLOC_CTX + * @param mods An initialized ADS_MODLIST + * @param name The attribute name to replace + * @param val The value to add + * @return ADS STATUS indicating success of add + **/ ADS_STATUS ads_mod_repl(TALLOC_CTX *ctx, ADS_MODLIST *mods, char *name, char *val) { @@ -524,12 +611,29 @@ ADS_STATUS ads_mod_repl(TALLOC_CTX *ctx, ADS_MODLIST *mods, return ads_mod_add_var(ctx, mods, LDAP_MOD_DELETE, name, NULL); } +/** + * Add a single string value to a mod list - for ADD + * @param ctx An initialized TALLOC_CTX + * @param mods An initialized ADS_MODLIST + * @param name The attribute name to add + * @param val The value to add + * @return ADS STATUS indicating success of add + **/ ADS_STATUS ads_mod_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, const char *name, const char *val) { return ads_mod_add_var(ctx, mods, LDAP_MOD_ADD, name, val, NULL); } +/** + * Add a single berval value to a mod list - for ADD + * @param ctx An initialized TALLOC_CTX + * @param mods An initialized ADS_MODLIST + * @param name The attribute name to add + * @param size The size of of the value + * @param val The value to add + * @return ADS STATUS indicating success of add + **/ ADS_STATUS ads_mod_add_len(TALLOC_CTX *ctx, ADS_MODLIST *mods, char *name, size_t size, char *val) { @@ -545,6 +649,15 @@ ADS_STATUS ads_mod_add_len(TALLOC_CTX *ctx, ADS_MODLIST *mods, return ads_mod_add_ber(ctx, mods, LDAP_MOD_ADD, name, bval, NULL); } +/** + * Add a single berval value to a mod list - for REPLACE + * @param ctx An initialized TALLOC_CTX + * @param mods An initialized ADS_MODLIST + * @param name The attribute name to replace + * @param size The size of of the value + * @param val The value to add + * @return ADS STATUS indicating success of add + **/ ADS_STATUS ads_mod_repl_len(TALLOC_CTX *ctx, ADS_MODLIST *mods, const char *name, size_t size, char *val) { @@ -565,6 +678,13 @@ ADS_STATUS ads_mod_repl_len(TALLOC_CTX *ctx, ADS_MODLIST *mods, } } +/** + * Perform an ldap modify + * @param ads connection to ads server + * @param mod_dn DistinguishedName to modify + * @param mods list of modifications to perform + * @return status of modify + **/ ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, ADS_MODLIST mods) { int ret,i; @@ -590,6 +710,13 @@ ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, ADS_MODLIST mods) return ADS_ERROR(ret); } +/** + * Perform an ldap add + * @param ads connection to ads server + * @param new_dn DistinguishedName to add + * @param mods list of attributes and values for DN + * @return status of add + **/ ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ADS_MODLIST mods) { int i; @@ -602,17 +729,24 @@ ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ADS_MODLIST mods) return ADS_ERROR(ldap_add_s(ads->ld, new_dn, mods)); } +/** + * Delete a DistinguishedName + * @param ads connection to ads server + * @param new_dn DistinguishedName to delete + * @return status of delete + **/ ADS_STATUS ads_del_dn(ADS_STRUCT *ads, char *del_dn) { return ADS_ERROR(ldap_delete(ads->ld, del_dn)); } -/* - build an org unit string - if org unit is Computers or blank then assume a container, otherwise - assume a \ separated list of organisational units - caller must free -*/ +/** + * Build an org unit string + * if org unit is Computers or blank then assume a container, otherwise + * assume a \ separated list of organisational units + * @param org_unit Organizational unit + * @return org unit string - caller must free + **/ char *ads_ou_string(const char *org_unit) { if (!org_unit || !*org_unit || strcasecmp(org_unit, "Computers") == 0) { @@ -785,23 +919,29 @@ static void ads_dump_field(char *field, void **values, void *data_area) } } -/* - dump a result from LDAP on stdout - used for debugging -*/ +/** + * Dump a result from LDAP on stdout + * used for debugging + * @param ads connection to ads server + * @param res Results to dump + **/ void ads_dump(ADS_STRUCT *ads, void *res) { ads_process_results(ads, res, ads_dump_field, NULL); } -/* - Walk through results, calling a function for each entry found. - The function receives a field name, a berval * array of values, - and a data area passed through from the start. The function is - called once with null for field and values at the end of each - entry. -*/ +/** + * Walk through results, calling a function for each entry found. + * The function receives a field name, a berval * array of values, + * and a data area passed through from the start. The function is + * called once with null for field and values at the end of each + * entry. + * @param ads connection to ads server + * @param res Results to process + * @param fn Function for processing each result + * @param data_area user-defined area to pass to function + **/ void ads_process_results(ADS_STRUCT *ads, void *res, void(*fn)(char *, void **, void *), void *data_area) @@ -830,6 +970,15 @@ void ads_process_results(ADS_STRUCT *ads, void *res, } } +/** + * Walk through an entry, calling a function for each attribute found. + * The function receives a field name, a berval * array of values, + * and a data area passed through from the start. + * @param ads connection to ads server + * @param res Results to process + * @param fn Function for processing each result + * @param data_area user-defined area to pass to function + **/ void ads_process_entry(ADS_STRUCT *ads, void *msg, void(*fn)(ADS_STRUCT *, char *, void **, void *), void *data_area) @@ -850,18 +999,25 @@ void ads_process_entry(ADS_STRUCT *ads, void *msg, } ber_free(b, 0); } -/* - count how many replies are in a LDAPMessage -*/ +/** + * count how many replies are in a LDAPMessage + * @param ads connection to ads server + * @param res Results to count + * @return number of replies + **/ int ads_count_replies(ADS_STRUCT *ads, void *res) { return ldap_count_entries(ads->ld, (LDAPMessage *)res); } -/* - join a machine to a realm, creating the machine account - and setting the machine password -*/ +/** + * Join a machine to a realm + * Creates the machine account and sets the machine password + * @param ads connection to ads server + * @param hostname name of host to add + * @param org_unit Organizational unit to place machine in + * @return status of join + **/ ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *hostname, const char *org_unit) { ADS_STATUS status; @@ -900,9 +1056,12 @@ ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *hostname, const char *org return status; } -/* - delete a machine from the realm -*/ +/** + * Delete a machine from the realm + * @param ads connection to ads server + * @param hostname Machine to remove + * @return status of delete + **/ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) { ADS_STATUS status; @@ -938,9 +1097,13 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) return status; } -/* - add machine account to existing security descriptor -*/ +/** + * add machine account to existing security descriptor + * @param ads connection to ads server + * @param hostname machine to add + * @param dn DN of security descriptor + * @return status + **/ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) { const char *attrs[] = {"ntSecurityDescriptor", "objectSid", 0}; @@ -1016,6 +1179,13 @@ ads_set_sd_error: return ADS_ERROR(LDAP_NO_MEMORY); } +/** + * Set the machine account password + * @param ads connection to ads server + * @param hostname machine whose password is being set + * @param password new password + * @return status of password change + **/ ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads, const char *hostname, const char *password) @@ -1041,25 +1211,36 @@ ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads, return status; } -/* - pull the first entry from a ADS result -*/ +/** + * pull the first entry from a ADS result + * @param ads connection to ads server + * @param res Results of search + * @return first entry from result + **/ void *ads_first_entry(ADS_STRUCT *ads, void *res) { return (void *)ldap_first_entry(ads->ld, (LDAPMessage *)res); } -/* - pull the next entry from a ADS result -*/ +/** + * pull the next entry from a ADS result + * @param ads connection to ads server + * @param res Results of search + * @return next entry from result + **/ void *ads_next_entry(ADS_STRUCT *ads, void *res) { return (void *)ldap_next_entry(ads->ld, (LDAPMessage *)res); } -/* - pull a single string from a ADS result -*/ +/** + * pull a single string from a ADS result + * @param ads connection to ads server + * @param mem_ctx TALLOC_CTX to use for allocating result string + * @param msg Results of search + * @param field Attribute to retrieve + * @return Result string in talloc context + **/ char *ads_pull_string(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, void *msg, const char *field) { @@ -1076,8 +1257,13 @@ char *ads_pull_string(ADS_STRUCT *ads, return ret; } -/* - pull a single uint32 from a ADS result +/** + * pull a single uint32 from a ADS result + * @param ads connection to ads server + * @param msg Results of search + * @param field Attribute to retrieve + * @param v Pointer to int to store result + * @return boolean inidicating success */ BOOL ads_pull_uint32(ADS_STRUCT *ads, void *msg, const char *field, uint32 *v) @@ -1096,8 +1282,13 @@ BOOL ads_pull_uint32(ADS_STRUCT *ads, return True; } -/* - pull a single DOM_SID from a ADS result +/** + * pull a single DOM_SID from a ADS result + * @param ads connection to ads server + * @param msg Results of search + * @param field Attribute to retrieve + * @param sid Pointer to sid to store result + * @return boolean inidicating success */ BOOL ads_pull_sid(ADS_STRUCT *ads, void *msg, const char *field, DOM_SID *sid) @@ -1117,10 +1308,15 @@ BOOL ads_pull_sid(ADS_STRUCT *ads, return ret; } -/* - pull an array of DOM_SIDs from a ADS result - return the count of SIDs pulled -*/ +/** + * pull an array of DOM_SIDs from a ADS result + * @param ads connection to ads server + * @param mem_ctx TALLOC_CTX for allocating sid array + * @param msg Results of search + * @param field Attribute to retrieve + * @param sids pointer to sid array to allocate + * @return the count of SIDs pulled + **/ int ads_pull_sids(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, void *msg, const char *field, DOM_SID **sids) { @@ -1147,7 +1343,13 @@ int ads_pull_sids(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, } -/* find the update serial number - this is the core of the ldap cache */ +/** + * find the update serial number - this is the core of the ldap cache + * @param ads connection to ads server + * @param ads connection to ADS server + * @param usn Pointer to retrieved update serial number + * @return status of search + **/ ADS_STATUS ads_USN(ADS_STRUCT *ads, uint32 *usn) { const char *attrs[] = {"highestCommittedUSN", NULL}; @@ -1167,10 +1369,13 @@ ADS_STATUS ads_USN(ADS_STRUCT *ads, uint32 *usn) } -/* find the servers name and realm - this can be done before authentication - The ldapServiceName field on w2k looks like this: - vnet3.home.samba.org:win2000-vnet3$@VNET3.HOME.SAMBA.ORG -*/ +/** + * Find the servers name and realm - this can be done before authentication + * The ldapServiceName field on w2k looks like this: + * vnet3.home.samba.org:win2000-vnet3$@VNET3.HOME.SAMBA.ORG + * @param ads connection to ads server + * @return status of search + **/ ADS_STATUS ads_server_info(ADS_STRUCT *ads) { const char *attrs[] = {"ldapServiceName", NULL}; @@ -1224,9 +1429,15 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads) } -/* - find the list of trusted domains -*/ +/** + * find the list of trusted domains + * @param ads connection to ads server + * @param mem_ctx TALLOC_CTX for allocating results + * @param num_trusts pointer to number of trusts + * @param names pointer to trusted domain name list + * @param sids pointer to list of sids of trusted domains + * @return the count of SIDs pulled + **/ ADS_STATUS ads_trusted_domains(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, int *num_trusts, char ***names, DOM_SID **sids) { @@ -1264,7 +1475,12 @@ ADS_STATUS ads_trusted_domains(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, return ADS_SUCCESS; } -/* find the domain sid for our domain */ +/** + * find the domain sid for our domain + * @param ads connection to ads server + * @param sid Pointer to domain sid + * @return status of search + **/ ADS_STATUS ads_domain_sid(ADS_STRUCT *ads, DOM_SID *sid) { const char *attrs[] = {"objectSid", NULL}; -- cgit From f6929068a19ef65fad5928982fd4ac4434e1763e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 15 Apr 2002 04:55:37 +0000 Subject: by using a prompter function we can avoid the bug in the MIT kerberos libraries with handling blank passwords. (This used to be commit 59d755ffb57c322a104ff8f52819956cafff1bac) --- source3/libads/kerberos.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 194a71275e..85518a6769 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -24,6 +24,28 @@ #ifdef HAVE_KRB5 +/* + we use a prompter to avoid a crash bug in the kerberos libs when + dealing with empty passwords + this prompter is just a string copy ... +*/ +static krb5_error_code +kerb_prompter(krb5_context ctx, void *data, + const char *name, + const char *banner, + int num_prompts, + krb5_prompt prompts[]) +{ + if (num_prompts == 0) return 0; + + memset(prompts[0].reply->data, 0, prompts[0].reply->length); + if (prompts[0].reply->length > 0) { + strncpy(prompts[0].reply->data, data, prompts[0].reply->length-1); + prompts[0].reply->length = strlen(prompts[0].reply->data); + } + return 0; +} + /* simulate a kinit, putting the tgt in the default cache location remus@snapserver.com @@ -36,11 +58,6 @@ int kerberos_kinit_password(const char *principal, const char *password) krb5_principal me; krb5_creds my_creds; - if (! *password) { - /* kerberos dies on an empty password! */ - return KRB5_PARSE_MALFORMED; - } - if ((code = krb5_init_context(&ctx))) return code; @@ -54,8 +71,9 @@ int kerberos_kinit_password(const char *principal, const char *password) return code; } - if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, (char*)password, NULL, - NULL, 0, NULL, NULL))) { + if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, NULL, + kerb_prompter, + password, 0, NULL, NULL))) { krb5_free_principal(ctx, me); krb5_free_context(ctx); return code; -- cgit From c0a991943044e038b78f796fb35d7625eb843d85 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 18 Apr 2002 06:56:44 +0000 Subject: fixed the fallback to a BDC for ADS connections (This used to be commit 3e58a1ee83ea0b4347ce24e566445cc6cb67bb3a) --- source3/libads/ads_struct.c | 19 ++++++++++++++++++- source3/libads/ldap.c | 24 ++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index 489f301ae2..816b616097 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -90,7 +90,12 @@ static char *find_ldap_server(ADS_STRUCT *ads) } /* get desperate, find the domain controller IP */ - if (resolve_name(lp_workgroup(), &ip, 0x1B)) { + if (resolve_name(ads->workgroup, &ip, 0x1B)) { + return strdup(inet_ntoa(ip)); + } + + /* or a BDC ... */ + if (resolve_name(ads->workgroup, &ip, 0x1C)) { return strdup(inet_ntoa(ip)); } @@ -115,6 +120,7 @@ static char *find_ldap_server(ADS_STRUCT *ads) initialise a ADS_STRUCT, ready for some ads_ ops */ ADS_STRUCT *ads_init(const char *realm, + const char *workgroup, const char *ldap_server, const char *bind_path, const char *password) @@ -124,7 +130,12 @@ ADS_STRUCT *ads_init(const char *realm, ads = (ADS_STRUCT *)smb_xmalloc(sizeof(*ads)); ZERO_STRUCTP(ads); + if (!workgroup) { + workgroup = lp_workgroup(); + } + ads->realm = realm? strdup(realm) : NULL; + ads->workgroup = strdup(workgroup); ads->ldap_server = ldap_server? strdup(ldap_server) : NULL; ads->bind_path = bind_path? strdup(bind_path) : NULL; ads->ldap_port = LDAP_PORT; @@ -153,6 +164,12 @@ ADS_STRUCT *ads_init(const char *realm, return ads; } +/* a simpler ads_init() interface using all defaults */ +ADS_STRUCT *ads_init_simple(void) +{ + return ads_init(NULL, NULL, NULL, NULL, NULL); +} + /* free the memory used by the ADS structure initialized with 'ads_init(...)' */ diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index e2e351bd4b..3b787c6a8f 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -46,9 +46,33 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) ads->last_attempt = time(NULL); ads->ld = ldap_open(ads->ldap_server, ads->ldap_port); + + /* if that failed then try each of the BDC's in turn */ + if (!ads->ld) { + struct in_addr *ip_list; + int count; + + if (get_dc_list(False, ads->workgroup, &ip_list, &count)) { + int i; + for (i=0;ild = ldap_open(inet_ntoa(ip_list[i]), + ads->ldap_port); + if (ads->ld) break; + } + if (ads->ld) { + free(ads->ldap_server); + ads->ldap_server = strdup(inet_ntoa(ip_list[i])); + } + free(ip_list); + } + } + if (!ads->ld) { return ADS_ERROR_SYSTEM(errno); } + + DEBUG(3,("Connected to LDAP server %s\n", ads->ldap_server)); + status = ads_server_info(ads); if (!ADS_ERR_OK(status)) { DEBUG(1,("Failed to get ldap server info\n")); -- cgit From fc78c773f8216df1bbaa88d9007cf3f5df386e3d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 19 Apr 2002 03:00:29 +0000 Subject: fixed trust relationships in ADS winbindd after breaking them with my BDC changes ... (This used to be commit 8096032663690eafb6bb8b4f405d6231389d4f80) --- source3/libads/ads_struct.c | 9 ++++++--- source3/libads/ldap.c | 8 ++++++-- 2 files changed, 12 insertions(+), 5 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index 816b616097..638dc0b22e 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -81,7 +81,8 @@ static char *find_ldap_server(ADS_STRUCT *ads) char *list = NULL; struct in_addr ip; - if (ads->realm && + if (ads->realm && + strcasecmp(ads->workgroup, lp_workgroup()) == 0 && ldap_domain2hostlist(ads->realm, &list) == LDAP_SUCCESS) { char *p; p = strchr(list, ':'); @@ -151,8 +152,10 @@ ADS_STRUCT *ads_init(const char *realm, ads->bind_path = ads_build_dn(ads->realm); } if (!ads->ldap_server) { - ads->ldap_server = strdup(lp_ads_server()); - if (!ads->ldap_server[0]) { + if (strcasecmp(ads->workgroup, lp_workgroup()) == 0) { + ads->ldap_server = strdup(lp_ads_server()); + } + if (!ads->ldap_server || !ads->ldap_server[0]) { ads->ldap_server = find_ldap_server(ads); } } diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 3b787c6a8f..543e53bcf8 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -45,7 +45,11 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) ads->last_attempt = time(NULL); - ads->ld = ldap_open(ads->ldap_server, ads->ldap_port); + ads->ld = NULL; + + if (ads->ldap_server) { + ads->ld = ldap_open(ads->ldap_server, ads->ldap_port); + } /* if that failed then try each of the BDC's in turn */ if (!ads->ld) { @@ -60,7 +64,7 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) if (ads->ld) break; } if (ads->ld) { - free(ads->ldap_server); + SAFE_FREE(ads->ldap_server); ads->ldap_server = strdup(inet_ntoa(ip_list[i])); } free(ip_list); -- cgit From 2503dc8eb80c35cbeef679a3d1b8d5579504cc47 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Thu, 9 May 2002 23:44:46 +0000 Subject: Add ads group account add function. (This used to be commit 180311a48cfa808ea9edc9f32558554b243b10eb) --- source3/libads/ldap_user.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap_user.c b/source3/libads/ldap_user.c index 13e68eb82e..c1a9a89e46 100644 --- a/source3/libads/ldap_user.c +++ b/source3/libads/ldap_user.c @@ -77,4 +77,37 @@ ADS_STATUS ads_add_user_acct(ADS_STRUCT *ads, const char *user, talloc_destroy(ctx); return status; } + +ADS_STATUS ads_add_group_acct(ADS_STRUCT *ads, const char *group, + const char *comment) +{ + TALLOC_CTX *ctx; + ADS_MODLIST mods; + ADS_STATUS status; + char *new_dn; + + if (!(ctx = talloc_init_named("ads_add_group_acct"))) + return ADS_ERROR(LDAP_NO_MEMORY); + + status = ADS_ERROR(LDAP_NO_MEMORY); + + if (!(new_dn = talloc_asprintf(ctx, "cn=%s,cn=Users,%s", group, + ads->bind_path))) + goto done; + if (!(mods = ads_init_mods(ctx))) + goto done; + + ads_mod_add(ctx, &mods, "cn", group); + ads_mod_add_var(ctx, &mods, LDAP_MOD_ADD, "objectClass", "top", + "group", NULL); + ads_mod_add(ctx, &mods, "name", group); + if (comment) + ads_mod_add(ctx, &mods, "description", comment); + ads_mod_add(ctx, &mods, "sAMAccountName", group); + status = ads_gen_add(ads, new_dn, mods); + + done: + talloc_destroy(ctx); + return status; +} #endif -- cgit From 31cda568c05624ef5e7fd2970c5f2733e67eedc3 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 17 May 2002 14:35:54 +0000 Subject: This is meant to be accessed via the helper fn, not directly. (This used to be commit b84882a628b3f2f0890322f25694c1932aa3e5ec) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 543e53bcf8..ab2828c23d 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1192,7 +1192,7 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) #endif if (!(mods = ads_init_mods(ctx))) return ADS_ERROR(LDAP_NO_MEMORY); - ads_mod_repl_len(ctx, &mods, attrs[0], sd_size, ps_wire.data_p); + ads_mod_repl_len(ctx, &mods, attrs[0], sd_size, prs_data_p(&ps_wire)); ret = ads_gen_mod(ads, dn, mods); prs_mem_free(&ps); -- cgit From d53b9f113a5f33eb93ae3e114b71fcfe18dcf666 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 3 Jun 2002 02:46:25 +0000 Subject: fixed a spelling mistake (This used to be commit 5a04ea1f0c41965bc735f38f4892dc37571734d6) --- source3/libads/disp_sec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/disp_sec.c b/source3/libads/disp_sec.c index ab8ceecb0c..35a7af7b36 100644 --- a/source3/libads/disp_sec.c +++ b/source3/libads/disp_sec.c @@ -123,7 +123,7 @@ void ads_disp_ace(SEC_ACE *sec_ace) } else if (sec_ace->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT) { access_type = "ALLOWED OBJECT"; } else if (sec_ace->type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT) { - access_type = "DEINED OBJECT"; + access_type = "DENIED OBJECT"; } else if (sec_ace->type == SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT) { access_type = "AUDIT OBJECT"; } -- cgit From 24b67730bf7bbf4414df99129a3cc20aa93dc0da Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Mon, 24 Jun 2002 17:50:02 +0000 Subject: Support utf8 on the wire for ads ldap. DN's are converted, as well as strings, though it is up to the calling function to decide whether values are strings or not. Attributes are not converted at this point, though support for it would be simple. I have tested it with users and groups using non-ascii chars, and if the check for alphanumeric user/domain names is removed form sesssetup.c, even a user with accented chars can connect, or even login (via winbind). I have also simplified the interfaces to ads_mod_*, though we will probably want to expand this by a few functions in the near future. We just had too many ways to do the same thing... (This used to be commit f924cb53580bc081ff34e45abba57629018c68d6) --- source3/libads/ldap.c | 532 +++++++++++++++++++----------------------- source3/libads/ldap_printer.c | 73 +++--- source3/libads/ldap_user.c | 29 +-- 3 files changed, 295 insertions(+), 339 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index ab2828c23d..b898eec7a9 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -30,6 +30,11 @@ * * The routines contained here should do the necessary ldap calls for * ads setups. + * + * Important note: attribute names passed into ads_ routines must + * already be in UTF-8 format. We do not convert them because in almost + * all cases, they are just ascii (which is represented with the same + * codepoints in UTF-8). This may have to change at some point **/ /** @@ -112,8 +117,8 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) * @param ads connection to ads server * @param bind_path Base dn for the search * @param scope Scope of search (LDAP_BASE | LDAP_ONE | LDAP_SUBTREE) - * @param exp Search expression - * @param attrs Attributes to retrieve + * @param exp Search expression - specified in local charset + * @param attrs Attributes to retrieve - specified in utf8 or ascii * @param res ** which will contain results - free res* with ads_msgfree() * @param count Number of entries retrieved on this page * @param cookie The paged results cookie to be returned on subsequent calls @@ -124,23 +129,16 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, const char **attrs, void **res, int *count, void **cookie) { - int rc; - int version; - LDAPControl PagedResults; - LDAPControl NoReferrals; + int rc, i, version; + char *utf8_exp, *utf8_path; + LDAPControl PagedResults, NoReferrals, *controls[3], **rcontrols; BerElement *cookie_be = NULL; struct berval *cookie_bv= NULL; - LDAPControl *controls[3]; - LDAPControl **rcontrols; - int i; *res = NULL; + /* Paged results only available on ldap v3 or later */ ldap_get_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); - - /* Paged results only available on ldap v3 or later, so check - version first before using, since at connect time we're - only v2. Not sure exactly why... */ if (version < LDAP_VERSION3) return ADS_ERROR(LDAP_NOT_SUPPORTED); @@ -171,20 +169,29 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, *res = NULL; /* we need to disable referrals as the openldap libs don't - seem to handle them correctly. They result in the result - record containing the server control being removed from the - result list (tridge) + handle them and paged results at the same time. Using them + together results in the result record containing the server + page control being removed from the result list (tridge/jmcd) leaving this in despite the control that says don't generate referrals, in case the server doesn't support it (jmcd) */ ldap_set_option(ads->ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF); - rc = ldap_search_ext_s(ads->ld, bind_path, scope, exp, + if (!push_utf8_allocate((void **) &utf8_exp, exp)) + utf8_exp = exp; + if (!push_utf8_allocate((void **) &utf8_path, bind_path)) + utf8_path = bind_path; + + rc = ldap_search_ext_s(ads->ld, utf8_path, scope, utf8_exp, (char **) attrs, 0, controls, NULL, NULL, LDAP_NO_LIMIT, (LDAPMessage **)res); + if (utf8_exp != exp) + SAFE_FREE(utf8_exp); + if (utf8_path != bind_path) + SAFE_FREE(utf8_path); ber_free(cookie_be, 1); ber_bvfree(cookie_bv); @@ -262,7 +269,6 @@ ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, next = ads_next_entry(ads, msg); ldap_add_result_entry((LDAPMessage **)res, msg); } - /* note that we do not free res2, as the memory is now part of the main returned list */ } @@ -276,15 +282,15 @@ ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, * @param ads connection to ads server * @param bind_path Base dn for the search * @param scope Scope of search (LDAP_BASE | LDAP_ONE | LDAP_SUBTREE) - * @param exp Search expression - * @param attrs Attributes to retrieve + * @param exp Search expression - specified in local charset + * @param attrs Attributes to retrieve - specified in UTF-8 or ascii * @param fn Function which takes attr name, values list, and data_area * @param data_area Pointer which is passed to function on each call * @return status of search **/ ADS_STATUS ads_do_search_all_fn(ADS_STRUCT *ads, const char *bind_path, int scope, const char *exp, const char **attrs, - void(*fn)(char *, void **, void *), + BOOL(*fn)(char *, void **, void *), void *data_area) { void *cookie = NULL; @@ -329,16 +335,25 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, { struct timeval timeout; int rc; + char *utf8_exp, *utf8_path; timeout.tv_sec = ADS_SEARCH_TIMEOUT; timeout.tv_usec = 0; *res = NULL; - rc = ldap_search_ext_s(ads->ld, - bind_path, scope, - exp, (char **) attrs, 0, NULL, NULL, + if (!push_utf8_allocate((void **) &utf8_exp, exp)) + utf8_exp = exp; + if (!push_utf8_allocate((void **) &utf8_path, bind_path)) + utf8_path = bind_path; + + rc = ldap_search_ext_s(ads->ld, utf8_path, scope, + utf8_exp, (char **) attrs, 0, NULL, NULL, &timeout, LDAP_NO_LIMIT, (LDAPMessage **)res); + if (utf8_exp != exp) + SAFE_FREE(utf8_exp); + if (utf8_path != bind_path) + SAFE_FREE(utf8_path); if (rc == LDAP_SIZELIMIT_EXCEEDED) { DEBUG(3,("Warning! sizelimit exceeded in ldap. Truncating.\n")); rc = 0; @@ -395,8 +410,7 @@ void ads_msgfree(ADS_STRUCT *ads, void *msg) **/ void ads_memfree(ADS_STRUCT *ads, void *mem) { - if (!mem) return; - ldap_memfree(mem); + SAFE_FREE(mem); } /** @@ -407,7 +421,12 @@ void ads_memfree(ADS_STRUCT *ads, void *mem) **/ char *ads_get_dn(ADS_STRUCT *ads, void *res) { - return ldap_get_dn(ads->ld, res); + char *utf8_dn, *unix_dn; + + utf8_dn = ldap_get_dn(ads->ld, res); + pull_utf8_allocate(&unix_dn, utf8_dn); + ldap_memfree(utf8_dn); + return unix_dn; } /** @@ -431,25 +450,6 @@ ADS_STATUS ads_find_machine_acct(ADS_STRUCT *ads, void **res, const char *host) return status; } -/* - duplicate an already-assembled list of values so that it can be - freed as part of the standard msgfree call -*/ -static char **ads_dup_values(TALLOC_CTX *ctx, char **values) -{ - char **newvals; - int i; -#define ADS_MAX_NUM_VALUES 32 - - for (i=0; values[i] && ibv_len == 0) return value; + + value->bv_len = in_val->bv_len; + value->bv_val = talloc_memdup(ctx, in_val->bv_val, in_val->bv_len); + return value; +} + +/* + Make a values list out of an array of (struct berval *) + */ +static struct berval **ads_dup_values(TALLOC_CTX *ctx, struct berval **in_vals) +{ + void **values; + int i; + + if (!in_vals) return NULL; + for (i=0; in_vals[i]; i++); /* count values */ + values = talloc_zero(ctx, (i+1)*sizeof(struct berval *)); + if (!values) return NULL; + + for (i=0; in_vals[i]; i++) { + values[i] = dup_berval(ctx, in_vals[i]); + } + return values; +} + +/* + UTF8-encode a values list out of an array of (char *) + */ +static char **ads_push_strvals(TALLOC_CTX *ctx, char **in_vals) +{ + void **values; + int i; + + if (!in_vals) return NULL; + for (i=0; in_vals[i]; i++); /* count values */ + values = talloc_zero(ctx, (i+1)*sizeof(char *)); + if (!values) return NULL; + + for (i=0; in_vals[i]; i++) { + push_utf8_talloc(ctx, &values[i], in_vals[i]); + } + return values; +} + +/* + Pull a (char *) array out of a UTF8-encoded values list + */ +static char **ads_pull_strvals(TALLOC_CTX *ctx, char **in_vals) +{ + void **values; + int i; + + if (!in_vals) return NULL; + for (i=0; in_vals[i]; i++); /* count values */ + values = talloc_zero(ctx, (i+1)*sizeof(char *)); + if (!values) return NULL; + + for (i=0; in_vals[i]; i++) { + pull_utf8_talloc(ctx, &values[i], in_vals[i]); + } + return values; +} + /* add an attribute to the list, with values list already constructed */ static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, - int mod_op, const char *name, char **values) + int mod_op, const char *name, void **invals) { int curmod; LDAPMod **modlist = (LDAPMod **) *mods; + void **values; + + if (!invals) { + values = NULL; + mod_op = LDAP_MOD_DELETE; + } else { + if (mod_op & LDAP_MOD_BVALUES) + values = ads_dup_values(ctx, invals); + else + values = ads_push_strvals(ctx, invals); + } /* find the first empty slot */ for (curmod=0; modlist[curmod] && modlist[curmod] != (LDAPMod *) -1; @@ -497,213 +582,62 @@ static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, if (mod_op & LDAP_MOD_BVALUES) modlist[curmod]->mod_bvalues = (struct berval **) values; else - modlist[curmod]->mod_values = values; + modlist[curmod]->mod_values = (char **) values; modlist[curmod]->mod_op = mod_op; return ADS_ERROR(LDAP_SUCCESS); } /** - * Add an already-constructed list of values to a mod list for an ADD + * Add a single string value to a mod list * @param ctx An initialized TALLOC_CTX * @param mods An initialized ADS_MODLIST * @param name The attribute name to add - * @param values Constructed values list to add + * @param val The value to add - NULL means DELETE * @return ADS STATUS indicating success of add **/ -ADS_STATUS ads_mod_add_list(TALLOC_CTX *ctx, ADS_MODLIST *mods, - char *name, char **values) -{ - char **newvals = ads_dup_values(ctx, values); - if (newvals) - return ads_modlist_add(ctx, mods, LDAP_MOD_ADD, name, newvals); - else - return ADS_ERROR(LDAP_NO_MEMORY); -} - -/** - * Add an already-constructed list of values to a mod list for a REPLACE - * @param ctx An initialized TALLOC_CTX - * @param mods An initialized ADS_MODLIST - * @param name The attribute name to add - * @param values Constructed values list to add - * @return ADS STATUS indicating success of add - **/ -ADS_STATUS ads_mod_repl_list(TALLOC_CTX *ctx, ADS_MODLIST *mods, - char *name, char **values) +ADS_STATUS ads_mod_str(TALLOC_CTX *ctx, ADS_MODLIST *mods, + const char *name, const char *val) { - char **newvals; - if (values && *values) { - if (!(newvals = ads_dup_values(ctx, values))) - return ADS_ERROR(LDAP_NO_MEMORY); - else - return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE, - name, newvals); - } - else + char *values[2] = {val, NULL}; + if (!val) return ads_modlist_add(ctx, mods, LDAP_MOD_DELETE, name, NULL); + return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE, name, + (void **) values); } /** - * Add any number of string values to a mod list - for ADD or REPLACE - * @param ctx An initialized TALLOC_CTX - * @param mods An initialized ADS_MODLIST - * @param mod_op Operation to perform (LDAP_MOD_ADD | LDAP_MOD_REPLACE) - * @param name The attribute name to add - * @param ... Any number of values, in (char *) form - * @return ADS STATUS indicating success of add - **/ -ADS_STATUS ads_mod_add_var(TALLOC_CTX *ctx, ADS_MODLIST *mods, - int mod_op, const char *name, ...) -{ - va_list ap; - int num_vals, i, do_op; - char *value, **values; - - /* count the number of values */ - va_start(ap, name); - for (num_vals=0; va_arg(ap, char *); num_vals++); - va_end(ap); - - if (num_vals) { - if (!(values = talloc_zero(ctx, sizeof(char *)*(num_vals+1)))) - return ADS_ERROR(LDAP_NO_MEMORY); - va_start(ap, name); - for (i=0; (value = (char *) va_arg(ap, char *)) && - i < num_vals; i++) - values[i] = value; - va_end(ap); - values[i] = NULL; - do_op = mod_op; - } else { - do_op = LDAP_MOD_DELETE; - values = NULL; - } - return ads_modlist_add(ctx, mods, do_op, name, values); -} - -/** - * Add any number of ber values to a mod list - for ADD or REPLACE + * Add an array of string values to a mod list * @param ctx An initialized TALLOC_CTX * @param mods An initialized ADS_MODLIST - * @param mod_op Operation to perform (LDAP_MOD_ADD | LDAP_MOD_REPLACE) * @param name The attribute name to add - * @param ... Any number of values, in (struct berval *) form - * @return ADS STATUS indicating success of add - **/ -ADS_STATUS ads_mod_add_ber(TALLOC_CTX *ctx, ADS_MODLIST *mods, - int mod_op, const char *name, ...) -{ - va_list ap; - int num_vals, i, do_op; - char *value, **values; - - /* count the number of values */ - va_start(ap, name); - for (num_vals=0; va_arg(ap, struct berval *); num_vals++); - va_end(ap); - - if (num_vals) { - if (!(values = talloc_zero(ctx, sizeof(struct berval) * - (num_vals + 1)))) - return ADS_ERROR(LDAP_NO_MEMORY); - va_start(ap, name); - for (i=0; (value = (char *) va_arg(ap, char *)) && - i < num_vals; i++) - values[i] = value; - va_end(ap); - values[i] = NULL; - do_op = mod_op; - } else { - do_op = LDAP_MOD_DELETE; - values = NULL; - } - do_op |= LDAP_MOD_BVALUES; - return ads_modlist_add(ctx, mods, do_op, name, values); -} - -/** - * Add a single string value to a mod list - for REPLACE - * @param ctx An initialized TALLOC_CTX - * @param mods An initialized ADS_MODLIST - * @param name The attribute name to replace - * @param val The value to add + * @param vals The array of string values to add - NULL means DELETE * @return ADS STATUS indicating success of add **/ -ADS_STATUS ads_mod_repl(TALLOC_CTX *ctx, ADS_MODLIST *mods, - char *name, char *val) +ADS_STATUS ads_mod_strlist(TALLOC_CTX *ctx, ADS_MODLIST *mods, + const char *name, const char **vals) { - if (val) - return ads_mod_add_var(ctx, mods, LDAP_MOD_REPLACE, - name, val, NULL); - else - return ads_mod_add_var(ctx, mods, LDAP_MOD_DELETE, name, NULL); -} - -/** - * Add a single string value to a mod list - for ADD - * @param ctx An initialized TALLOC_CTX - * @param mods An initialized ADS_MODLIST - * @param name The attribute name to add - * @param val The value to add - * @return ADS STATUS indicating success of add - **/ -ADS_STATUS ads_mod_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, - const char *name, const char *val) -{ - return ads_mod_add_var(ctx, mods, LDAP_MOD_ADD, name, val, NULL); + if (!vals) + return ads_modlist_add(ctx, mods, LDAP_MOD_DELETE, name, NULL); + return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE, name, + (void **) vals); } /** - * Add a single berval value to a mod list - for ADD + * Add a single ber-encoded value to a mod list * @param ctx An initialized TALLOC_CTX * @param mods An initialized ADS_MODLIST * @param name The attribute name to add - * @param size The size of of the value - * @param val The value to add - * @return ADS STATUS indicating success of add - **/ -ADS_STATUS ads_mod_add_len(TALLOC_CTX *ctx, ADS_MODLIST *mods, - char *name, size_t size, char *val) -{ - struct berval *bval = NULL; - - if (!(bval = talloc_zero(ctx, sizeof(struct berval *)))) - return ADS_ERROR(LDAP_NO_MEMORY); - if (!(bval->bv_val = talloc_zero(ctx, sizeof(char *)))) - return ADS_ERROR(LDAP_NO_MEMORY); - - bval->bv_val = val; - bval->bv_len = size; - return ads_mod_add_ber(ctx, mods, LDAP_MOD_ADD, name, bval, NULL); -} - -/** - * Add a single berval value to a mod list - for REPLACE - * @param ctx An initialized TALLOC_CTX - * @param mods An initialized ADS_MODLIST - * @param name The attribute name to replace - * @param size The size of of the value - * @param val The value to add + * @param val The value to add - NULL means DELETE * @return ADS STATUS indicating success of add **/ -ADS_STATUS ads_mod_repl_len(TALLOC_CTX *ctx, ADS_MODLIST *mods, - const char *name, size_t size, char *val) +ADS_STATUS ads_mod_ber(TALLOC_CTX *ctx, ADS_MODLIST *mods, + const char *name, const struct berval *val) { - struct berval *bval = NULL; - - if (!(bval = talloc_zero(ctx, sizeof(struct berval *)))) - return ADS_ERROR(LDAP_NO_MEMORY); - + struct berval *values[2] = {val, NULL}; if (!val) - return ads_mod_add_ber(ctx, mods, LDAP_MOD_DELETE, name, NULL); - else { - if (!(bval->bv_val = talloc_zero(ctx, sizeof(char *)))) - return ADS_ERROR(LDAP_NO_MEMORY); - bval->bv_val = val; - bval->bv_len = size; - return ads_mod_add_ber(ctx, mods, LDAP_MOD_REPLACE, name, - bval, NULL); - } + return ads_modlist_add(ctx, mods, LDAP_MOD_DELETE, name, NULL); + return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE|LDAP_MOD_BVALUES, + name, (void **) values); } /** @@ -716,6 +650,7 @@ ADS_STATUS ads_mod_repl_len(TALLOC_CTX *ctx, ADS_MODLIST *mods, ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, ADS_MODLIST mods) { int ret,i; + char *utf8_dn = NULL; /* this control is needed to modify that contains a currently non-existent attribute (but allowable for the object) to run @@ -729,12 +664,15 @@ ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, ADS_MODLIST mods) controls[0] = &PermitModify; controls[1] = NULL; + push_utf8_allocate(&utf8_dn, mod_dn); + /* find the end of the list, marked by NULL or -1 */ for(i=0;(mods[i]!=0)&&(mods[i]!=(LDAPMod *) -1);i++); /* make sure the end of the list is NULL */ mods[i] = NULL; - ret = ldap_modify_ext_s(ads->ld, mod_dn, (LDAPMod **) mods, - controls, NULL); + ret = ldap_modify_ext_s(ads->ld, utf8_dn ? utf8_dn : mod_dn, + (LDAPMod **) mods, controls, NULL); + SAFE_FREE(utf8_dn); return ADS_ERROR(ret); } @@ -747,14 +685,19 @@ ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, ADS_MODLIST mods) **/ ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ADS_MODLIST mods) { - int i; + int ret, i; + char *utf8_dn = NULL; + push_utf8_allocate(&utf8_dn, new_dn); + /* find the end of the list, marked by NULL or -1 */ for(i=0;(mods[i]!=0)&&(mods[i]!=(LDAPMod *) -1);i++); /* make sure the end of the list is NULL */ mods[i] = NULL; - return ADS_ERROR(ldap_add_s(ads->ld, new_dn, mods)); + ret = ldap_add_s(ads->ld, utf8_dn ? utf8_dn : new_dn, mods); + SAFE_FREE(utf8_dn); + return ADS_ERROR(ret); } /** @@ -765,7 +708,11 @@ ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ADS_MODLIST mods) **/ ADS_STATUS ads_del_dn(ADS_STRUCT *ads, char *del_dn) { - return ADS_ERROR(ldap_delete(ads->ld, del_dn)); + int ret; + char *utf8_dn = NULL; + push_utf8_allocate(&utf8_dn, del_dn); + ret = ldap_delete(ads->ld, utf8_dn ? utf8_dn : del_dn); + return ADS_ERROR(ret); } /** @@ -797,6 +744,8 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, char *ou_str; TALLOC_CTX *ctx; ADS_MODLIST mods; + const char *objectClass[] = {"top", "person", "organizationalPerson", + "user", "computer", NULL}; if (!(ctx = talloc_init_named("machine_account"))) return ADS_ERROR(LDAP_NO_MEMORY); @@ -824,17 +773,15 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, if (!(mods = ads_init_mods(ctx))) goto done; - ads_mod_add(ctx, &mods, "cn", hostname); - ads_mod_add(ctx, &mods, "sAMAccountName", samAccountName); - ads_mod_add_var(ctx, &mods, LDAP_MOD_ADD, "objectClass", - "top", "person", "organizationalPerson", - "user", "computer", NULL); - ads_mod_add(ctx, &mods, "userPrincipalName", host_upn); - ads_mod_add(ctx, &mods, "servicePrincipalName", host_spn); - ads_mod_add(ctx, &mods, "dNSHostName", hostname); - ads_mod_add(ctx, &mods, "userAccountControl", controlstr); - ads_mod_add(ctx, &mods, "operatingSystem", "Samba"); - ads_mod_add(ctx, &mods, "operatingSystemVersion", VERSION); + ads_mod_str(ctx, &mods, "cn", hostname); + ads_mod_str(ctx, &mods, "sAMAccountName", samAccountName); + ads_mod_strlist(ctx, &mods, "objectClass", objectClass); + ads_mod_str(ctx, &mods, "userPrincipalName", host_upn); + ads_mod_str(ctx, &mods, "servicePrincipalName", host_spn); + ads_mod_str(ctx, &mods, "dNSHostName", hostname); + ads_mod_str(ctx, &mods, "userAccountControl", controlstr); + ads_mod_str(ctx, &mods, "operatingSystem", "Samba"); + ads_mod_str(ctx, &mods, "operatingSystemVersion", VERSION); ads_gen_add(ads, new_dn, mods); ret = ads_set_machine_sd(ads, hostname, new_dn); @@ -918,33 +865,39 @@ static void dump_string(const char *field, struct berval **values) used for debugging */ -static void ads_dump_field(char *field, void **values, void *data_area) +static BOOL ads_dump_field(char *field, void **values, void *data_area) { struct { char *name; + BOOL string; void (*handler)(const char *, struct berval **); } handlers[] = { - {"objectGUID", dump_binary}, - {"nTSecurityDescriptor", dump_sd}, - {"objectSid", dump_sid}, - {NULL, NULL} + {"objectGUID", False, dump_binary}, + {"nTSecurityDescriptor", False, dump_sd}, + {"objectSid", False, dump_sid}, + {NULL, True, NULL} }; int i; if (!field) { /* must be end of an entry */ printf("\n"); - return; + return False; } for (i=0; handlers[i].name; i++) { if (StrCaseCmp(handlers[i].name, field) == 0) { + if (!values) /* first time, indicate string or not */ + return handlers[i].string; handlers[i].handler(field, (struct berval **) values); break; } } if (!handlers[i].name) { + if (!values) /* first time, indicate string conversion */ + return True; dump_string(field, (struct berval **) values); } + return False; } /** @@ -971,62 +924,56 @@ void ads_dump(ADS_STRUCT *ads, void *res) * @param data_area user-defined area to pass to function **/ void ads_process_results(ADS_STRUCT *ads, void *res, - void(*fn)(char *, void **, void *), + BOOL(*fn)(char *, void **, void *), void *data_area) { void *msg; + TALLOC_CTX *ctx; + + if (!(ctx = talloc_init())) + return; for (msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) { - char *field; + char *utf8_field; BerElement *b; - for (field = ldap_first_attribute(ads->ld, (LDAPMessage *)msg, &b); - field; - field = ldap_next_attribute(ads->ld, (LDAPMessage *)msg, b)) { - struct berval **values; - - values = ldap_get_values_len(ads->ld, (LDAPMessage *)msg, field); - fn(field, (void **) values, data_area); - - ldap_value_free_len(values); - ldap_memfree(field); + for (utf8_field=ldap_first_attribute(ads->ld, + (LDAPMessage *)msg,&b); + utf8_field; + utf8_field=ldap_next_attribute(ads->ld, + (LDAPMessage *)msg,b)) { + struct berval **ber_vals; + char **str_vals, **utf8_vals; + char *field; + BOOL string; + + pull_utf8_talloc(ctx, (void **) &field, utf8_field); + string = fn(field, NULL, data_area); + + if (string) { + utf8_vals = ldap_get_values(ads->ld, + (LDAPMessage *)msg, field); + str_vals = ads_pull_strvals(ctx, utf8_vals); + fn(field, (void **) str_vals, data_area); + ldap_value_free(utf8_vals); + } else { + ber_vals = ldap_get_values_len(ads->ld, + (LDAPMessage *)msg, field); + fn(field, (void **) ber_vals, data_area); + + ldap_value_free_len(ber_vals); + } + ldap_memfree(utf8_field); } ber_free(b, 0); + talloc_destroy_pool(ctx); fn(NULL, NULL, data_area); /* completed an entry */ } + talloc_destroy(ctx); } -/** - * Walk through an entry, calling a function for each attribute found. - * The function receives a field name, a berval * array of values, - * and a data area passed through from the start. - * @param ads connection to ads server - * @param res Results to process - * @param fn Function for processing each result - * @param data_area user-defined area to pass to function - **/ -void ads_process_entry(ADS_STRUCT *ads, void *msg, - void(*fn)(ADS_STRUCT *, char *, void **, void *), - void *data_area) -{ - char *field; - BerElement *b; - - for (field = ldap_first_attribute(ads->ld, (LDAPMessage *)msg, &b); - field; - field = ldap_next_attribute(ads->ld, (LDAPMessage *)msg, b)) { - struct berval **values; - - values = ldap_get_values_len(ads->ld, (LDAPMessage *)msg, field); - fn(ads, field, (void **) values, data_area); - - ldap_value_free_len(values); - ldap_memfree(field); - } - ber_free(b, 0); -} /** * count how many replies are in a LDAPMessage * @param ads connection to ads server @@ -1138,6 +1085,7 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) char *exp = 0; size_t sd_size = 0; struct berval **bvals = 0; + struct berval bval = {0, NULL}; prs_struct ps; prs_struct ps_wire; @@ -1192,7 +1140,9 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) #endif if (!(mods = ads_init_mods(ctx))) return ADS_ERROR(LDAP_NO_MEMORY); - ads_mod_repl_len(ctx, &mods, attrs[0], sd_size, prs_data_p(&ps_wire)); + bval.bv_len = sd_size; + bval.bv_val = prs_data_p(&ps_wire); + ads_mod_ber(ctx, &mods, attrs[0], &bval); ret = ads_gen_mod(ads, dn, mods); prs_mem_free(&ps); @@ -1274,12 +1224,18 @@ char *ads_pull_string(ADS_STRUCT *ads, { char **values; char *ret = NULL; + char *ux_string; + int rc; values = ldap_get_values(ads->ld, msg, field); if (!values) return NULL; if (values[0]) { - ret = talloc_strdup(mem_ctx, values[0]); + rc = pull_utf8_talloc(mem_ctx, (void **)&ux_string, + values[0]); + if (rc != -1) + ret = ux_string; + } ldap_value_free(values); return ret; diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index 52771ba39a..64ae8252c8 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -31,7 +31,7 @@ ADS_STATUS ads_find_printer_on_server(ADS_STRUCT *ads, void **res, char *printer, char *servername) { ADS_STATUS status; - char *srv_dn, *exp; + char *srv_dn, **srv_cn, *exp; const char *attrs[] = {"*", "nTSecurityDescriptor", NULL}; status = ads_find_machine_acct(ads, res, servername); @@ -41,12 +41,14 @@ ADS_STATUS ads_find_printer_on_server(ADS_STRUCT *ads, void **res, return status; } srv_dn = ldap_get_dn(ads->ld, *res); + srv_cn = ldap_explode_dn(srv_dn, 1); ads_msgfree(ads, *res); - asprintf(&exp, "(printerName=%s)", printer); - status = ads_do_search(ads, srv_dn, LDAP_SCOPE_SUBTREE, - exp, attrs, res); + asprintf(&exp, "(cn=%s-%s)", srv_cn[0], printer); + status = ads_search(ads, res, exp, attrs); + ldap_memfree(srv_dn); + ldap_value_free(srv_cn); free(exp); return status; } @@ -68,33 +70,33 @@ ADS_STATUS ads_mod_printer_entry(ADS_STRUCT *ads, char *prt_dn, mods = ads_init_mods(ctx); /* add the attributes to the list - required ones first */ - ads_mod_repl(ctx, &mods, "printerName", prt->printerName); - ads_mod_repl(ctx, &mods, "serverName", prt->serverName); - ads_mod_repl(ctx, &mods, "shortServerName", prt->shortServerName); - ads_mod_repl(ctx, &mods, "uNCName", prt->uNCName); - ads_mod_repl(ctx, &mods, "versionNumber", prt->versionNumber); + ads_mod_str(ctx, &mods, "printerName", prt->printerName); + ads_mod_str(ctx, &mods, "serverName", prt->serverName); + ads_mod_str(ctx, &mods, "shortServerName", prt->shortServerName); + ads_mod_str(ctx, &mods, "uNCName", prt->uNCName); + ads_mod_str(ctx, &mods, "versionNumber", prt->versionNumber); /* now the optional ones */ - ads_mod_repl_list(ctx, &mods, "description", prt->description); - ads_mod_repl(ctx, &mods, "assetNumber",prt->assetNumber); - ads_mod_repl(ctx, &mods, "bytesPerMinute",prt->bytesPerMinute); - ads_mod_repl(ctx, &mods, "defaultPriority",prt->defaultPriority); - ads_mod_repl(ctx, &mods, "driverName", prt->driverName); - ads_mod_repl(ctx, &mods, "driverVersion",prt->driverVersion); - ads_mod_repl(ctx, &mods, "location", prt->location); - ads_mod_repl(ctx, &mods, "operatingSystem",prt->operatingSystem); - ads_mod_repl(ctx, &mods, "operatingSystemHotfix", + ads_mod_strlist(ctx, &mods, "description", prt->description); + ads_mod_str(ctx, &mods, "assetNumber",prt->assetNumber); + ads_mod_str(ctx, &mods, "bytesPerMinute",prt->bytesPerMinute); + ads_mod_str(ctx, &mods, "defaultPriority",prt->defaultPriority); + ads_mod_str(ctx, &mods, "driverName", prt->driverName); + ads_mod_str(ctx, &mods, "driverVersion",prt->driverVersion); + ads_mod_str(ctx, &mods, "location", prt->location); + ads_mod_str(ctx, &mods, "operatingSystem",prt->operatingSystem); + ads_mod_str(ctx, &mods, "operatingSystemHotfix", prt->operatingSystemHotfix); - ads_mod_repl(ctx, &mods, "operatingSystemServicePack", + ads_mod_str(ctx, &mods, "operatingSystemServicePack", prt->operatingSystemServicePack); - ads_mod_repl(ctx, &mods, "operatingSystemVersion", + ads_mod_str(ctx, &mods, "operatingSystemVersion", prt->operatingSystemVersion); - ads_mod_repl(ctx, &mods, "physicalLocationObject", + ads_mod_str(ctx, &mods, "physicalLocationObject", prt->physicalLocationObject); - ads_mod_repl_list(ctx, &mods, "portName", prt->portName); - ads_mod_repl(ctx, &mods, "printStartTime", prt->printStartTime); - ads_mod_repl(ctx, &mods, "printEndTime", prt->printEndTime); - ads_mod_repl_list(ctx, &mods, "printBinNames", prt->printBinNames); + ads_mod_strlist(ctx, &mods, "portName", prt->portName); + ads_mod_str(ctx, &mods, "printStartTime", prt->printStartTime); + ads_mod_str(ctx, &mods, "printEndTime", prt->printEndTime); + ads_mod_strlist(ctx, &mods, "printBinNames", prt->printBinNames); /*... and many others */ /* do the ldap modify */ @@ -124,12 +126,12 @@ static ADS_STATUS ads_add_printer_entry(ADS_STRUCT *ads, char *prt_dn, return ADS_ERROR(LDAP_NO_MEMORY); /* These are the fields a printQueue must contain */ - ads_mod_add(ctx, &mods, "uNCName", prt->uNCName); - ads_mod_add(ctx, &mods, "versionNumber", prt->versionNumber); - ads_mod_add(ctx, &mods, "serverName", prt->serverName); - ads_mod_add(ctx, &mods, "shortServerName", prt->shortServerName); - ads_mod_add(ctx, &mods, "printerName", prt->printerName); - ads_mod_add(ctx, &mods, "objectClass", "printQueue"); + ads_mod_str(ctx, &mods, "uNCName", prt->uNCName); + ads_mod_str(ctx, &mods, "versionNumber", prt->versionNumber); + ads_mod_str(ctx, &mods, "serverName", prt->serverName); + ads_mod_str(ctx, &mods, "shortServerName", prt->shortServerName); + ads_mod_str(ctx, &mods, "printerName", prt->printerName); + ads_mod_str(ctx, &mods, "objectClass", "printQueue"); status = ads_gen_add(ads, prt_dn, mods); @@ -157,14 +159,11 @@ ADS_STATUS ads_add_printer(ADS_STRUCT *ads, const ADS_PRINTER_ENTRY *prt) prt->shortServerName)); return status; } - host_dn = ldap_get_dn(ads->ld, res); + host_dn = ads_get_dn(ads, res); ads_msgfree(ads, res); - /* printer dn is cn=server-printer followed by host dn */ - asprintf(&prt_dn, "cn=%s-%s,%s", prt->shortServerName, - prt->printerName, host_dn); - - status = ads_search_dn(ads, &res, prt_dn, attrs); + ads_find_printer_on_server(ads, &res, prt->printerName, + prt->shortServerName); if (ADS_ERR_OK(status) && ads_count_replies(ads, res)) { DEBUG(1, ("ads_add_printer: printer %s already exists\n", diff --git a/source3/libads/ldap_user.c b/source3/libads/ldap_user.c index c1a9a89e46..d0b6c2ca8c 100644 --- a/source3/libads/ldap_user.c +++ b/source3/libads/ldap_user.c @@ -44,6 +44,8 @@ ADS_STATUS ads_add_user_acct(ADS_STRUCT *ads, const char *user, ADS_MODLIST mods; ADS_STATUS status; char *upn, *new_dn, *name, *controlstr; + const char *objectClass[] = {"top", "person", "organizationalPerson", + "user", NULL}; if (fullname && *fullname) name = fullname; else name = user; @@ -63,14 +65,13 @@ ADS_STATUS ads_add_user_acct(ADS_STRUCT *ads, const char *user, if (!(mods = ads_init_mods(ctx))) goto done; - ads_mod_add(ctx, &mods, "cn", name); - ads_mod_add_var(ctx, &mods, LDAP_MOD_ADD, "objectClass", "top", - "person", "organizationalPerson", "user", NULL); - ads_mod_add(ctx, &mods, "userPrincipalName", upn); - ads_mod_add(ctx, &mods, "name", name); - ads_mod_add(ctx, &mods, "displayName", name); - ads_mod_add(ctx, &mods, "sAMAccountName", user); - ads_mod_add(ctx, &mods, "userAccountControl", controlstr); + ads_mod_str(ctx, &mods, "cn", name); + ads_mod_strlist(ctx, &mods, "objectClass", objectClass); + ads_mod_str(ctx, &mods, "userPrincipalName", upn); + ads_mod_str(ctx, &mods, "name", name); + ads_mod_str(ctx, &mods, "displayName", name); + ads_mod_str(ctx, &mods, "sAMAccountName", user); + ads_mod_str(ctx, &mods, "userAccountControl", controlstr); status = ads_gen_add(ads, new_dn, mods); done: @@ -85,6 +86,7 @@ ADS_STATUS ads_add_group_acct(ADS_STRUCT *ads, const char *group, ADS_MODLIST mods; ADS_STATUS status; char *new_dn; + const char *objectClass[] = {"top", "group", NULL}; if (!(ctx = talloc_init_named("ads_add_group_acct"))) return ADS_ERROR(LDAP_NO_MEMORY); @@ -97,13 +99,12 @@ ADS_STATUS ads_add_group_acct(ADS_STRUCT *ads, const char *group, if (!(mods = ads_init_mods(ctx))) goto done; - ads_mod_add(ctx, &mods, "cn", group); - ads_mod_add_var(ctx, &mods, LDAP_MOD_ADD, "objectClass", "top", - "group", NULL); - ads_mod_add(ctx, &mods, "name", group); + ads_mod_str(ctx, &mods, "cn", group); + ads_mod_strlist(ctx, &mods, "objectClass",objectClass); + ads_mod_str(ctx, &mods, "name", group); if (comment) - ads_mod_add(ctx, &mods, "description", comment); - ads_mod_add(ctx, &mods, "sAMAccountName", group); + ads_mod_str(ctx, &mods, "description", comment); + ads_mod_str(ctx, &mods, "sAMAccountName", group); status = ads_gen_add(ads, new_dn, mods); done: -- cgit From 0327428f27b453e5b2c1ee2751ab87d7716144d7 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 25 Jun 2002 02:29:09 +0000 Subject: Break up samba's object dependencies, and its prototype includes. Now smbclient, net, and swat use their own proto files - now the global proto.h The change to libads/kerberos.c was to break up the dependency on secrets.c - we want to be able to write an ADS client that doesn't need local secrets. I have other breakups in the works - I will remove the dependency of rpc_parse on passdb (and therefore secrets.c) shortly. (NOTE: This patch does *not* break up includes.h, or other such forbidden actions). Andrew Bartlett (This used to be commit edb41dad2df0ae3db364dbc3896cc75956262edf) --- source3/libads/kerberos.c | 123 ------------------------------- source3/libads/kerberos_verify.c | 151 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 151 insertions(+), 123 deletions(-) create mode 100644 source3/libads/kerberos_verify.c (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 85518a6769..1ba5d978e8 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -129,128 +129,5 @@ int ads_kinit_password(ADS_STRUCT *ads) return ret; } -/* - verify an incoming ticket and parse out the principal name and - authorization_data if available -*/ -NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, - char **principal, DATA_BLOB *auth_data) -{ - krb5_context context; - krb5_auth_context auth_context = NULL; - krb5_keytab keytab = NULL; - krb5_data packet; - krb5_ticket *tkt = NULL; - krb5_data salt; - krb5_encrypt_block eblock; - int ret; - krb5_keyblock * key; - krb5_principal host_princ; - char *host_princ_s; - extern pstring global_myname; - fstring myname; - char *password_s; - krb5_data password; - - if (!secrets_init()) { - DEBUG(1,("secrets_init failed\n")); - return NT_STATUS_LOGON_FAILURE; - } - - password_s = secrets_fetch_machine_password(); - if (!password_s) { - DEBUG(1,("failed to fetch machine password\n")); - return NT_STATUS_LOGON_FAILURE; - } - - password.data = password_s; - password.length = strlen(password_s); - - ret = krb5_init_context(&context); - if (ret) { - DEBUG(1,("krb5_init_context failed (%s)\n", error_message(ret))); - return NT_STATUS_LOGON_FAILURE; - } - - ret = krb5_set_default_realm(context, ads->realm); - if (ret) { - DEBUG(1,("krb5_set_default_realm failed (%s)\n", error_message(ret))); - ads_destroy(&ads); - return NT_STATUS_LOGON_FAILURE; - } - - /* this whole process is far more complex than I would - like. We have to go through all this to allow us to store - the secret internally, instead of using /etc/krb5.keytab */ - ret = krb5_auth_con_init(context, &auth_context); - if (ret) { - DEBUG(1,("krb5_auth_con_init failed (%s)\n", error_message(ret))); - return NT_STATUS_LOGON_FAILURE; - } - - fstrcpy(myname, global_myname); - strlower(myname); - asprintf(&host_princ_s, "HOST/%s@%s", myname, lp_realm()); - ret = krb5_parse_name(context, host_princ_s, &host_princ); - if (ret) { - DEBUG(1,("krb5_parse_name(%s) failed (%s)\n", host_princ_s, error_message(ret))); - return NT_STATUS_LOGON_FAILURE; - } - - ret = krb5_principal2salt(context, host_princ, &salt); - if (ret) { - DEBUG(1,("krb5_principal2salt failed (%s)\n", error_message(ret))); - return NT_STATUS_LOGON_FAILURE; - } - - if (!(key = (krb5_keyblock *)malloc(sizeof(*key)))) { - return NT_STATUS_NO_MEMORY; - } - - krb5_use_enctype(context, &eblock, ENCTYPE_DES_CBC_MD5); - - ret = krb5_string_to_key(context, &eblock, key, &password, &salt); - if (ret) { - DEBUG(1,("krb5_string_to_key failed (%s)\n", error_message(ret))); - return NT_STATUS_LOGON_FAILURE; - } - - krb5_auth_con_setuseruserkey(context, auth_context, key); - - packet.length = ticket->length; - packet.data = (krb5_pointer)ticket->data; - -#if 0 - file_save("/tmp/ticket.dat", ticket->data, ticket->length); -#endif - - if ((ret = krb5_rd_req(context, &auth_context, &packet, - NULL, keytab, NULL, &tkt))) { - DEBUG(3,("krb5_rd_req with auth failed (%s)\n", - error_message(ret))); - return NT_STATUS_LOGON_FAILURE; - } - - if (tkt->enc_part2) { - *auth_data = data_blob(tkt->enc_part2->authorization_data[0]->contents, - tkt->enc_part2->authorization_data[0]->length); - } - -#if 0 - if (tkt->enc_part2) { - file_save("/tmp/authdata.dat", - tkt->enc_part2->authorization_data[0]->contents, - tkt->enc_part2->authorization_data[0]->length); - } -#endif - - if ((ret = krb5_unparse_name(context, tkt->enc_part2->client, principal))) { - DEBUG(3,("krb5_unparse_name failed (%s)\n", - error_message(ret))); - return NT_STATUS_LOGON_FAILURE; - } - - return NT_STATUS_OK; -} #endif diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c new file mode 100644 index 0000000000..dac90908c4 --- /dev/null +++ b/source3/libads/kerberos_verify.c @@ -0,0 +1,151 @@ +/* + Unix SMB/CIFS implementation. + kerberos utility library + Copyright (C) Andrew Tridgell 2001 + Copyright (C) Remus Koos 2001 + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +#ifdef HAVE_KRB5 + +/* + verify an incoming ticket and parse out the principal name and + authorization_data if available +*/ +NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, + char **principal, DATA_BLOB *auth_data) +{ + krb5_context context; + krb5_auth_context auth_context = NULL; + krb5_keytab keytab = NULL; + krb5_data packet; + krb5_ticket *tkt = NULL; + krb5_data salt; + krb5_encrypt_block eblock; + int ret; + krb5_keyblock * key; + krb5_principal host_princ; + char *host_princ_s; + extern pstring global_myname; + fstring myname; + char *password_s; + krb5_data password; + + if (!secrets_init()) { + DEBUG(1,("secrets_init failed\n")); + return NT_STATUS_LOGON_FAILURE; + } + + password_s = secrets_fetch_machine_password(); + if (!password_s) { + DEBUG(1,("failed to fetch machine password\n")); + return NT_STATUS_LOGON_FAILURE; + } + + password.data = password_s; + password.length = strlen(password_s); + + ret = krb5_init_context(&context); + if (ret) { + DEBUG(1,("krb5_init_context failed (%s)\n", error_message(ret))); + return NT_STATUS_LOGON_FAILURE; + } + + ret = krb5_set_default_realm(context, ads->realm); + if (ret) { + DEBUG(1,("krb5_set_default_realm failed (%s)\n", error_message(ret))); + ads_destroy(&ads); + return NT_STATUS_LOGON_FAILURE; + } + + /* this whole process is far more complex than I would + like. We have to go through all this to allow us to store + the secret internally, instead of using /etc/krb5.keytab */ + ret = krb5_auth_con_init(context, &auth_context); + if (ret) { + DEBUG(1,("krb5_auth_con_init failed (%s)\n", error_message(ret))); + return NT_STATUS_LOGON_FAILURE; + } + + fstrcpy(myname, global_myname); + strlower(myname); + asprintf(&host_princ_s, "HOST/%s@%s", myname, lp_realm()); + ret = krb5_parse_name(context, host_princ_s, &host_princ); + if (ret) { + DEBUG(1,("krb5_parse_name(%s) failed (%s)\n", host_princ_s, error_message(ret))); + return NT_STATUS_LOGON_FAILURE; + } + + ret = krb5_principal2salt(context, host_princ, &salt); + if (ret) { + DEBUG(1,("krb5_principal2salt failed (%s)\n", error_message(ret))); + return NT_STATUS_LOGON_FAILURE; + } + + if (!(key = (krb5_keyblock *)malloc(sizeof(*key)))) { + return NT_STATUS_NO_MEMORY; + } + + krb5_use_enctype(context, &eblock, ENCTYPE_DES_CBC_MD5); + + ret = krb5_string_to_key(context, &eblock, key, &password, &salt); + if (ret) { + DEBUG(1,("krb5_string_to_key failed (%s)\n", error_message(ret))); + return NT_STATUS_LOGON_FAILURE; + } + + krb5_auth_con_setuseruserkey(context, auth_context, key); + + packet.length = ticket->length; + packet.data = (krb5_pointer)ticket->data; + +#if 0 + file_save("/tmp/ticket.dat", ticket->data, ticket->length); +#endif + + if ((ret = krb5_rd_req(context, &auth_context, &packet, + NULL, keytab, NULL, &tkt))) { + DEBUG(3,("krb5_rd_req with auth failed (%s)\n", + error_message(ret))); + return NT_STATUS_LOGON_FAILURE; + } + + if (tkt->enc_part2) { + *auth_data = data_blob(tkt->enc_part2->authorization_data[0]->contents, + tkt->enc_part2->authorization_data[0]->length); + } + +#if 0 + if (tkt->enc_part2) { + file_save("/tmp/authdata.dat", + tkt->enc_part2->authorization_data[0]->contents, + tkt->enc_part2->authorization_data[0]->length); + } +#endif + + if ((ret = krb5_unparse_name(context, tkt->enc_part2->client, principal))) { + DEBUG(3,("krb5_unparse_name failed (%s)\n", + error_message(ret))); + return NT_STATUS_LOGON_FAILURE; + } + + return NT_STATUS_OK; +} + +#endif -- cgit From f0a0c6955bc4e7c587fa06599759ad9be5750573 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Wed, 26 Jun 2002 17:27:30 +0000 Subject: Reduce compiler warnings. (This used to be commit b361089360068b91e9f4d221abdc3c8351596a7f) --- source3/libads/ldap.c | 64 +++++++++++++++++++++++++++++---------------------- 1 file changed, 36 insertions(+), 28 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index b898eec7a9..22d7ed3ebf 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -37,6 +37,12 @@ * codepoints in UTF-8). This may have to change at some point **/ +/* This is used to get reduce other const warnings to just this fn */ +static void * ads_unconst_ptr(const void *const_ptr) +{ + return const_ptr; +} + /** * Connect to the LDAP server * @param ads Pointer to an existing ADS_STRUCT @@ -179,14 +185,13 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, ldap_set_option(ads->ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF); if (!push_utf8_allocate((void **) &utf8_exp, exp)) - utf8_exp = exp; + utf8_exp = ads_unconst_ptr(exp); if (!push_utf8_allocate((void **) &utf8_path, bind_path)) - utf8_path = bind_path; + utf8_path = ads_unconst_ptr(bind_path); rc = ldap_search_ext_s(ads->ld, utf8_path, scope, utf8_exp, - (char **) attrs, 0, controls, NULL, - NULL, LDAP_NO_LIMIT, - (LDAPMessage **)res); + ads_unconst_ptr(attrs), 0, controls, + NULL, NULL, LDAP_NO_LIMIT, (LDAPMessage **)res); if (utf8_exp != exp) SAFE_FREE(utf8_exp); @@ -342,12 +347,12 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, *res = NULL; if (!push_utf8_allocate((void **) &utf8_exp, exp)) - utf8_exp = exp; + utf8_exp = ads_unconst_ptr(exp); if (!push_utf8_allocate((void **) &utf8_path, bind_path)) - utf8_path = bind_path; + utf8_path = ads_unconst_ptr(bind_path); - rc = ldap_search_ext_s(ads->ld, utf8_path, scope, - utf8_exp, (char **) attrs, 0, NULL, NULL, + rc = ldap_search_ext_s(ads->ld, utf8_path, scope, utf8_exp, + ads_unconst_ptr(attrs), 0, NULL, NULL, &timeout, LDAP_NO_LIMIT, (LDAPMessage **)res); if (utf8_exp != exp) @@ -424,7 +429,7 @@ char *ads_get_dn(ADS_STRUCT *ads, void *res) char *utf8_dn, *unix_dn; utf8_dn = ldap_get_dn(ads->ld, res); - pull_utf8_allocate(&unix_dn, utf8_dn); + pull_utf8_allocate((void **) &unix_dn, utf8_dn); ldap_memfree(utf8_dn); return unix_dn; } @@ -491,12 +496,13 @@ static struct berval *dup_berval(TALLOC_CTX *ctx, struct berval *in_val) */ static struct berval **ads_dup_values(TALLOC_CTX *ctx, struct berval **in_vals) { - void **values; + struct berval **values; int i; if (!in_vals) return NULL; for (i=0; in_vals[i]; i++); /* count values */ - values = talloc_zero(ctx, (i+1)*sizeof(struct berval *)); + values = (struct berval **) talloc_zero(ctx, + (i+1)*sizeof(struct berval *)); if (!values) return NULL; for (i=0; in_vals[i]; i++) { @@ -510,16 +516,16 @@ static struct berval **ads_dup_values(TALLOC_CTX *ctx, struct berval **in_vals) */ static char **ads_push_strvals(TALLOC_CTX *ctx, char **in_vals) { - void **values; + char **values; int i; if (!in_vals) return NULL; for (i=0; in_vals[i]; i++); /* count values */ - values = talloc_zero(ctx, (i+1)*sizeof(char *)); + values = (char ** ) talloc_zero(ctx, (i+1)*sizeof(char *)); if (!values) return NULL; for (i=0; in_vals[i]; i++) { - push_utf8_talloc(ctx, &values[i], in_vals[i]); + push_utf8_talloc(ctx, (void **) &values[i], in_vals[i]); } return values; } @@ -529,16 +535,16 @@ static char **ads_push_strvals(TALLOC_CTX *ctx, char **in_vals) */ static char **ads_pull_strvals(TALLOC_CTX *ctx, char **in_vals) { - void **values; + char **values; int i; if (!in_vals) return NULL; for (i=0; in_vals[i]; i++); /* count values */ - values = talloc_zero(ctx, (i+1)*sizeof(char *)); + values = (char **) talloc_zero(ctx, (i+1)*sizeof(char *)); if (!values) return NULL; for (i=0; in_vals[i]; i++) { - pull_utf8_talloc(ctx, &values[i], in_vals[i]); + pull_utf8_talloc(ctx, (void **) &values[i], in_vals[i]); } return values; } @@ -558,9 +564,11 @@ static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, mod_op = LDAP_MOD_DELETE; } else { if (mod_op & LDAP_MOD_BVALUES) - values = ads_dup_values(ctx, invals); + values = (void **) ads_dup_values(ctx, + (struct berval **)invals); else - values = ads_push_strvals(ctx, invals); + values = (void **) ads_push_strvals(ctx, + (char **) invals); } /* find the first empty slot */ @@ -578,7 +586,7 @@ static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, if (!(modlist[curmod] = talloc_zero(ctx, sizeof(LDAPMod)))) return ADS_ERROR(LDAP_NO_MEMORY); - modlist[curmod]->mod_type = name; + modlist[curmod]->mod_type = ads_unconst_ptr(name); if (mod_op & LDAP_MOD_BVALUES) modlist[curmod]->mod_bvalues = (struct berval **) values; else @@ -598,7 +606,7 @@ static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, ADS_STATUS ads_mod_str(TALLOC_CTX *ctx, ADS_MODLIST *mods, const char *name, const char *val) { - char *values[2] = {val, NULL}; + char *values[2] = {ads_unconst_ptr(val), NULL}; if (!val) return ads_modlist_add(ctx, mods, LDAP_MOD_DELETE, name, NULL); return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE, name, @@ -618,8 +626,8 @@ ADS_STATUS ads_mod_strlist(TALLOC_CTX *ctx, ADS_MODLIST *mods, { if (!vals) return ads_modlist_add(ctx, mods, LDAP_MOD_DELETE, name, NULL); - return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE, name, - (void **) vals); + return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE, + ads_unconst_ptr(name), ads_unconst_ptr(vals)); } /** @@ -633,7 +641,7 @@ ADS_STATUS ads_mod_strlist(TALLOC_CTX *ctx, ADS_MODLIST *mods, ADS_STATUS ads_mod_ber(TALLOC_CTX *ctx, ADS_MODLIST *mods, const char *name, const struct berval *val) { - struct berval *values[2] = {val, NULL}; + struct berval *values[2] = {ads_unconst_ptr(val), NULL}; if (!val) return ads_modlist_add(ctx, mods, LDAP_MOD_DELETE, name, NULL); return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE|LDAP_MOD_BVALUES, @@ -664,7 +672,7 @@ ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, ADS_MODLIST mods) controls[0] = &PermitModify; controls[1] = NULL; - push_utf8_allocate(&utf8_dn, mod_dn); + push_utf8_allocate((void **) &utf8_dn, mod_dn); /* find the end of the list, marked by NULL or -1 */ for(i=0;(mods[i]!=0)&&(mods[i]!=(LDAPMod *) -1);i++); @@ -688,7 +696,7 @@ ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ADS_MODLIST mods) int ret, i; char *utf8_dn = NULL; - push_utf8_allocate(&utf8_dn, new_dn); + push_utf8_allocate((void **) &utf8_dn, new_dn); /* find the end of the list, marked by NULL or -1 */ for(i=0;(mods[i]!=0)&&(mods[i]!=(LDAPMod *) -1);i++); @@ -710,7 +718,7 @@ ADS_STATUS ads_del_dn(ADS_STRUCT *ads, char *del_dn) { int ret; char *utf8_dn = NULL; - push_utf8_allocate(&utf8_dn, del_dn); + push_utf8_allocate((void **) &utf8_dn, del_dn); ret = ldap_delete(ads->ld, utf8_dn ? utf8_dn : del_dn); return ADS_ERROR(ret); } -- cgit From f90e74afbabf86b54cf0d0cc137bff167d23d768 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 28 Jun 2002 19:25:11 +0000 Subject: Const cleanup...should only be 2 warnings left from calling lib/util_str.c str_list_copy(). Perhaps its proto should be fixed. (This used to be commit b81bc2b34b620c24a148435d9913bd1a1528c983) --- source3/libads/ldap.c | 275 +++++++++++++++++++++++++++++--------------------- 1 file changed, 158 insertions(+), 117 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 22d7ed3ebf..c95cb4ad90 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -37,12 +37,6 @@ * codepoints in UTF-8). This may have to change at some point **/ -/* This is used to get reduce other const warnings to just this fn */ -static void * ads_unconst_ptr(const void *const_ptr) -{ - return const_ptr; -} - /** * Connect to the LDAP server * @param ads Pointer to an existing ADS_STRUCT @@ -115,6 +109,81 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) return ads_sasl_bind(ads); } +/* + Duplicate a struct berval into talloc'ed memory + */ +static struct berval *dup_berval(TALLOC_CTX *ctx, const struct berval *in_val) +{ + struct berval *value; + + if (!in_val) return NULL; + + value = talloc_zero(ctx, sizeof(struct berval)); + if (in_val->bv_len == 0) return value; + + value->bv_len = in_val->bv_len; + value->bv_val = talloc_memdup(ctx, in_val->bv_val, in_val->bv_len); + return value; +} + +/* + Make a values list out of an array of (struct berval *) + */ +static struct berval **ads_dup_values(TALLOC_CTX *ctx, + const struct berval **in_vals) +{ + struct berval **values; + int i; + + if (!in_vals) return NULL; + for (i=0; in_vals[i]; i++); /* count values */ + values = (struct berval **) talloc_zero(ctx, + (i+1)*sizeof(struct berval *)); + if (!values) return NULL; + + for (i=0; in_vals[i]; i++) { + values[i] = dup_berval(ctx, in_vals[i]); + } + return values; +} + +/* + UTF8-encode a values list out of an array of (char *) + */ +static char **ads_push_strvals(TALLOC_CTX *ctx, const char **in_vals) +{ + char **values; + int i; + + if (!in_vals) return NULL; + for (i=0; in_vals[i]; i++); /* count values */ + values = (char ** ) talloc_zero(ctx, (i+1)*sizeof(char *)); + if (!values) return NULL; + + for (i=0; in_vals[i]; i++) { + push_utf8_talloc(ctx, (void **) &values[i], in_vals[i]); + } + return values; +} + +/* + Pull a (char *) array out of a UTF8-encoded values list + */ +static char **ads_pull_strvals(TALLOC_CTX *ctx, const char **in_vals) +{ + char **values; + int i; + + if (!in_vals) return NULL; + for (i=0; in_vals[i]; i++); /* count values */ + values = (char **) talloc_zero(ctx, (i+1)*sizeof(char *)); + if (!values) return NULL; + + for (i=0; in_vals[i]; i++) { + pull_utf8_talloc(ctx, (void **) &values[i], in_vals[i]); + } + return values; +} /** * Do a search with paged results. cookie must be null on the first @@ -136,17 +205,45 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, int *count, void **cookie) { int rc, i, version; - char *utf8_exp, *utf8_path; + char *utf8_exp, *utf8_path, **search_attrs; LDAPControl PagedResults, NoReferrals, *controls[3], **rcontrols; BerElement *cookie_be = NULL; struct berval *cookie_bv= NULL; + TALLOC_CTX *ctx; *res = NULL; + if (!(ctx = talloc_init())) + return ADS_ERROR(LDAP_NO_MEMORY); + + /* 0 means the conversion worked but the result was empty + so we only fail if it's negative. In any case, it always + at least nulls out the dest */ + if ((push_utf8_talloc(ctx, (void **) &utf8_exp, exp) < 0) || + (push_utf8_talloc(ctx, (void **) &utf8_path, bind_path) < 0)) { + rc = LDAP_NO_MEMORY; + goto done; + } + + if (!attrs || !(*attrs)) + search_attrs = NULL; + else { + /* This would be the utf8-encoded version...*/ + /* if (!(search_attrs = ads_push_strvals(ctx, attrs))) */ + if (!(str_list_copy(&search_attrs, (char **) attrs))) + { + rc = LDAP_NO_MEMORY; + goto done; + } + } + + /* Paged results only available on ldap v3 or later */ ldap_get_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); - if (version < LDAP_VERSION3) - return ADS_ERROR(LDAP_NOT_SUPPORTED); + if (version < LDAP_VERSION3) { + rc = LDAP_NOT_SUPPORTED; + goto done; + } cookie_be = ber_alloc_t(LBER_USE_DER); if (cookie && *cookie) { @@ -184,32 +281,23 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, */ ldap_set_option(ads->ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF); - if (!push_utf8_allocate((void **) &utf8_exp, exp)) - utf8_exp = ads_unconst_ptr(exp); - if (!push_utf8_allocate((void **) &utf8_path, bind_path)) - utf8_path = ads_unconst_ptr(bind_path); - rc = ldap_search_ext_s(ads->ld, utf8_path, scope, utf8_exp, - ads_unconst_ptr(attrs), 0, controls, + search_attrs, 0, controls, NULL, NULL, LDAP_NO_LIMIT, (LDAPMessage **)res); - if (utf8_exp != exp) - SAFE_FREE(utf8_exp); - if (utf8_path != bind_path) - SAFE_FREE(utf8_path); ber_free(cookie_be, 1); ber_bvfree(cookie_bv); if (rc) { DEBUG(3,("ldap_search_ext_s(%s) -> %s\n", exp, ldap_err2string(rc))); - return ADS_ERROR(rc); + goto done; } rc = ldap_parse_result(ads->ld, *res, NULL, NULL, NULL, NULL, &rcontrols, 0); if (!rcontrols) { - return ADS_ERROR(rc); + goto done; } for (i=0; rcontrols[i]; i++) { @@ -229,7 +317,12 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, } } ldap_controls_free(rcontrols); - + +done: + talloc_destroy(ctx); + /* if/when we decide to utf8-encode attrs, take out this next line */ + str_list_free(&search_attrs); + return ADS_ERROR(rc); } @@ -340,30 +433,50 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, { struct timeval timeout; int rc; - char *utf8_exp, *utf8_path; + char *utf8_exp, *utf8_path, **search_attrs = NULL; + TALLOC_CTX *ctx; + + if (!(ctx = talloc_init())) + return ADS_ERROR(LDAP_NO_MEMORY); + + /* 0 means the conversion worked but the result was empty + so we only fail if it's negative. In any case, it always + at least nulls out the dest */ + if ((push_utf8_talloc(ctx, (void **) &utf8_exp, exp) < 0) || + (push_utf8_talloc(ctx, (void **) &utf8_path, bind_path) < 0)) { + rc = LDAP_NO_MEMORY; + goto done; + } + + if (!attrs || !(*attrs)) + search_attrs = NULL; + else { + /* This would be the utf8-encoded version...*/ + /* if (!(search_attrs = ads_push_strvals(ctx, attrs))) */ + if (!(str_list_copy(&search_attrs, (char **) attrs))) + { + rc = LDAP_NO_MEMORY; + goto done; + } + } timeout.tv_sec = ADS_SEARCH_TIMEOUT; timeout.tv_usec = 0; *res = NULL; - if (!push_utf8_allocate((void **) &utf8_exp, exp)) - utf8_exp = ads_unconst_ptr(exp); - if (!push_utf8_allocate((void **) &utf8_path, bind_path)) - utf8_path = ads_unconst_ptr(bind_path); - rc = ldap_search_ext_s(ads->ld, utf8_path, scope, utf8_exp, - ads_unconst_ptr(attrs), 0, NULL, NULL, + search_attrs, 0, NULL, NULL, &timeout, LDAP_NO_LIMIT, (LDAPMessage **)res); - if (utf8_exp != exp) - SAFE_FREE(utf8_exp); - if (utf8_path != bind_path) - SAFE_FREE(utf8_path); if (rc == LDAP_SIZELIMIT_EXCEEDED) { DEBUG(3,("Warning! sizelimit exceeded in ldap. Truncating.\n")); rc = 0; } + done: + talloc_destroy(ctx); + /* if/when we decide to utf8-encode attrs, take out this next line */ + str_list_free(&search_attrs); return ADS_ERROR(rc); } /** @@ -474,86 +587,13 @@ ADS_MODLIST ads_init_mods(TALLOC_CTX *ctx) return mods; } -/* - Duplicate a struct berval into talloc'ed memory - */ -static struct berval *dup_berval(TALLOC_CTX *ctx, struct berval *in_val) -{ - struct berval *value; - - if (!in_val) return NULL; - - value = talloc_zero(ctx, sizeof(struct berval)); - if (in_val->bv_len == 0) return value; - - value->bv_len = in_val->bv_len; - value->bv_val = talloc_memdup(ctx, in_val->bv_val, in_val->bv_len); - return value; -} - -/* - Make a values list out of an array of (struct berval *) - */ -static struct berval **ads_dup_values(TALLOC_CTX *ctx, struct berval **in_vals) -{ - struct berval **values; - int i; - - if (!in_vals) return NULL; - for (i=0; in_vals[i]; i++); /* count values */ - values = (struct berval **) talloc_zero(ctx, - (i+1)*sizeof(struct berval *)); - if (!values) return NULL; - - for (i=0; in_vals[i]; i++) { - values[i] = dup_berval(ctx, in_vals[i]); - } - return values; -} - -/* - UTF8-encode a values list out of an array of (char *) - */ -static char **ads_push_strvals(TALLOC_CTX *ctx, char **in_vals) -{ - char **values; - int i; - - if (!in_vals) return NULL; - for (i=0; in_vals[i]; i++); /* count values */ - values = (char ** ) talloc_zero(ctx, (i+1)*sizeof(char *)); - if (!values) return NULL; - - for (i=0; in_vals[i]; i++) { - push_utf8_talloc(ctx, (void **) &values[i], in_vals[i]); - } - return values; -} - -/* - Pull a (char *) array out of a UTF8-encoded values list - */ -static char **ads_pull_strvals(TALLOC_CTX *ctx, char **in_vals) -{ - char **values; - int i; - - if (!in_vals) return NULL; - for (i=0; in_vals[i]; i++); /* count values */ - values = (char **) talloc_zero(ctx, (i+1)*sizeof(char *)); - if (!values) return NULL; - - for (i=0; in_vals[i]; i++) { - pull_utf8_talloc(ctx, (void **) &values[i], in_vals[i]); - } - return values; -} /* add an attribute to the list, with values list already constructed */ static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, - int mod_op, const char *name, void **invals) + int mod_op, const char *name, + const void **invals) { int curmod; LDAPMod **modlist = (LDAPMod **) *mods; @@ -565,10 +605,10 @@ static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, } else { if (mod_op & LDAP_MOD_BVALUES) values = (void **) ads_dup_values(ctx, - (struct berval **)invals); + (const struct berval **)invals); else values = (void **) ads_push_strvals(ctx, - (char **) invals); + (const char **) invals); } /* find the first empty slot */ @@ -586,7 +626,7 @@ static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, if (!(modlist[curmod] = talloc_zero(ctx, sizeof(LDAPMod)))) return ADS_ERROR(LDAP_NO_MEMORY); - modlist[curmod]->mod_type = ads_unconst_ptr(name); + modlist[curmod]->mod_type = talloc_strdup(ctx, name); if (mod_op & LDAP_MOD_BVALUES) modlist[curmod]->mod_bvalues = (struct berval **) values; else @@ -606,11 +646,11 @@ static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, ADS_STATUS ads_mod_str(TALLOC_CTX *ctx, ADS_MODLIST *mods, const char *name, const char *val) { - char *values[2] = {ads_unconst_ptr(val), NULL}; + const char *values[2] = {val, NULL}; if (!val) return ads_modlist_add(ctx, mods, LDAP_MOD_DELETE, name, NULL); return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE, name, - (void **) values); + (const void **) values); } /** @@ -627,7 +667,7 @@ ADS_STATUS ads_mod_strlist(TALLOC_CTX *ctx, ADS_MODLIST *mods, if (!vals) return ads_modlist_add(ctx, mods, LDAP_MOD_DELETE, name, NULL); return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE, - ads_unconst_ptr(name), ads_unconst_ptr(vals)); + name, (const void **) vals); } /** @@ -641,11 +681,11 @@ ADS_STATUS ads_mod_strlist(TALLOC_CTX *ctx, ADS_MODLIST *mods, ADS_STATUS ads_mod_ber(TALLOC_CTX *ctx, ADS_MODLIST *mods, const char *name, const struct berval *val) { - struct berval *values[2] = {ads_unconst_ptr(val), NULL}; + const struct berval *values[2] = {val, NULL}; if (!val) return ads_modlist_add(ctx, mods, LDAP_MOD_DELETE, name, NULL); return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE|LDAP_MOD_BVALUES, - name, (void **) values); + name, (const void **) values); } /** @@ -962,7 +1002,8 @@ void ads_process_results(ADS_STRUCT *ads, void *res, if (string) { utf8_vals = ldap_get_values(ads->ld, (LDAPMessage *)msg, field); - str_vals = ads_pull_strvals(ctx, utf8_vals); + str_vals = ads_pull_strvals(ctx, + (const char **) utf8_vals); fn(field, (void **) str_vals, data_area); ldap_value_free(utf8_vals); } else { -- cgit From 859b13577309912fc5b3591971412b2cb3a42f28 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 1 Jul 2002 07:30:40 +0000 Subject: ads_mod_ber should be static, not public this fixes the huge number of struct berval warnings on non-ads compiles (This used to be commit e7f588d8156856109623b5f5a3841c5d096b1185) --- source3/libads/ldap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index c95cb4ad90..1045b05812 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -678,8 +678,8 @@ ADS_STATUS ads_mod_strlist(TALLOC_CTX *ctx, ADS_MODLIST *mods, * @param val The value to add - NULL means DELETE * @return ADS STATUS indicating success of add **/ -ADS_STATUS ads_mod_ber(TALLOC_CTX *ctx, ADS_MODLIST *mods, - const char *name, const struct berval *val) +static ADS_STATUS ads_mod_ber(TALLOC_CTX *ctx, ADS_MODLIST *mods, + const char *name, const struct berval *val) { const struct berval *values[2] = {val, NULL}; if (!val) -- cgit From 9930b0b0650ae3e38c033c28672398425dd8228c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 1 Jul 2002 09:12:41 +0000 Subject: used findstatic.pl to make some variables static and remove some dead code (This used to be commit 91ad9041e9507d36eb3f40c23c5d4df61f139ef0) --- source3/libads/disp_sec.c | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/disp_sec.c b/source3/libads/disp_sec.c index 35a7af7b36..a930fd6fe0 100644 --- a/source3/libads/disp_sec.c +++ b/source3/libads/disp_sec.c @@ -52,7 +52,7 @@ static struct perm_mask_str { }; /* convert a security permissions into a string */ -void ads_disp_perms(uint32 type) +static void ads_disp_perms(uint32 type) { int i = 0; int j = 0; @@ -82,20 +82,8 @@ void ads_disp_perms(uint32 type) puts(""); } -/* Check if ACE has OBJECT type */ -BOOL ads_ace_object(uint8 type) -{ - if (type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT || - type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT || - type == SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT || - type == SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT) { - return True; - } - return False; -} - /* display ACE */ -void ads_disp_ace(SEC_ACE *sec_ace) +static void ads_disp_ace(SEC_ACE *sec_ace) { char *access_type = "UNKNOWN"; @@ -135,7 +123,7 @@ void ads_disp_ace(SEC_ACE *sec_ace) } /* display ACL */ -void ads_disp_acl(SEC_ACL *sec_acl, char *type) +static void ads_disp_acl(SEC_ACL *sec_acl, char *type) { if (!sec_acl) printf("------- (%s) ACL not present\n", type); -- cgit From 21b9280cf516045f3ffb7d5249087a127855a38d Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 8 Jul 2002 02:14:57 +0000 Subject: Kill off const warnings - add a pile of const to various places. (This used to be commit 1de04ec4735c19ec21cdef6e679cea17c734c5f6) --- source3/libads/ldap_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap_user.c b/source3/libads/ldap_user.c index d0b6c2ca8c..b6e3d189c5 100644 --- a/source3/libads/ldap_user.c +++ b/source3/libads/ldap_user.c @@ -43,7 +43,7 @@ ADS_STATUS ads_add_user_acct(ADS_STRUCT *ads, const char *user, TALLOC_CTX *ctx; ADS_MODLIST mods; ADS_STATUS status; - char *upn, *new_dn, *name, *controlstr; + const char *upn, *new_dn, *name, *controlstr; const char *objectClass[] = {"top", "person", "organizationalPerson", "user", NULL}; -- cgit From 83060558c98051fd96ed831e22e218497ba5dfd7 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Mon, 8 Jul 2002 20:46:54 +0000 Subject: Fix length in snprintf invocation to account for "dn:" in sasl gssapi bind. Also remove unused line which incremented pointer by the wrong length anyway. Provided by Anthony Liguori (aliguori@us.ibm.com). (This used to be commit 47b7a3e0f3d101a3bcffd33db6ef4c0672b57ae0) --- source3/libads/sasl.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index eb29c71fce..1b55453cac 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -171,8 +171,7 @@ ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) *p++ = max_msg_size>>16; *p++ = max_msg_size>>8; *p++ = max_msg_size; - snprintf(p, strlen(ads->bind_path)+1, "dn:%s", ads->bind_path); - p += strlen(ads->bind_path); + snprintf(p, strlen(ads->bind_path)+4, "dn:%s", ads->bind_path); output_token.length = strlen(ads->bind_path) + 8; -- cgit From 5ae8fa2df1e4e9b40200869ed946f3c8b9e4f2b3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 9 Jul 2002 15:06:51 +0000 Subject: make sure we disable referrals in all ldap searches - they are badly broken (This used to be commit 022073d140bae960613127a6d9422e443a8098c6) --- source3/libads/ldap.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 1045b05812..7e51c203ca 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -464,6 +464,9 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, timeout.tv_usec = 0; *res = NULL; + /* see the note in ads_do_paged_search - we *must* disable referrals */ + ldap_set_option(ads->ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF); + rc = ldap_search_ext_s(ads->ld, utf8_path, scope, utf8_exp, search_attrs, 0, NULL, NULL, &timeout, LDAP_NO_LIMIT, (LDAPMessage **)res); -- cgit From 8fb570e6e0c748a9e7bf3d4207302e8dfb6ae779 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 11 Jul 2002 03:41:09 +0000 Subject: this fixes the ads dump code a char** isn't quite the same thing as a struct berval** :) (This used to be commit a92834ea9460bc49be99d6d5b0d41a817e6f0824) --- source3/libads/ldap.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 7e51c203ca..c9ad3e08db 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -903,11 +903,11 @@ static void dump_sd(const char *filed, struct berval **values) /* dump a string result from ldap */ -static void dump_string(const char *field, struct berval **values) +static void dump_string(const char *field, char **values) { int i; for (i=0; values[i]; i++) { - printf("%s: %s\n", field, values[i]->bv_val); + printf("%s: %s\n", field, values[i]); } } @@ -946,7 +946,7 @@ static BOOL ads_dump_field(char *field, void **values, void *data_area) if (!handlers[i].name) { if (!values) /* first time, indicate string conversion */ return True; - dump_string(field, (struct berval **) values); + dump_string(field, (char **)values); } return False; } -- cgit From 5d827857560ecd23c0cd5179d73e1f14a7ed993a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 11 Jul 2002 05:28:08 +0000 Subject: this implements a completely new strategy for fetching group membership from an ADS server. We now use a 'member' query on the group and do a separate call to convert the resulting distinguished name to a name, rid etc. This is *much* faster for very large numbers of groups (on a quantum test system with 10000 groups it drops the time from an hour to about 35 seconds). strangely enough, this actually *increases* the amount of ldap traffic, its just that the MS LDAP server answers these queries much faster. (This used to be commit 5538048e4f6dd224b2990f3c6a3e99fd07065f77) --- source3/libads/ldap.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index c9ad3e08db..0f41269e3a 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1293,6 +1293,41 @@ char *ads_pull_string(ADS_STRUCT *ads, return ret; } +/** + * pull an array of strings from a ADS result + * @param ads connection to ads server + * @param mem_ctx TALLOC_CTX to use for allocating result string + * @param msg Results of search + * @param field Attribute to retrieve + * @return Result strings in talloc context + **/ +char **ads_pull_strings(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, void *msg, const char *field) +{ + char **values; + char **ret = NULL; + int i, n; + + values = ldap_get_values(ads->ld, msg, field); + if (!values) return NULL; + + for (i=0;values[i];i++) /* noop */ ; + n = i; + + ret = talloc(mem_ctx, sizeof(char *) * (n+1)); + + for (i=0;i Date: Fri, 12 Jul 2002 02:28:27 +0000 Subject: fix setting machine passwords in the case where a user account of the same name as the machine name exists. (we ended up setting the users password, not the machines password!) (This used to be commit fe1e6233c6f0a5654bcc3ab34f65bb570efc69b1) --- source3/libads/ldap.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 0f41269e3a..9d15c4e33c 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1231,7 +1231,11 @@ ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads, strlower(host); - asprintf(&principal, "%s@%s", host, ads->realm); + /* + we need to use the '$' form of the name here, as otherwise the + server might end up setting the password for a user instead + */ + asprintf(&principal, "%s$@%s", host, ads->realm); status = krb5_set_password(ads->kdc_server, principal, password); -- cgit From e90b65284812aaa5ff9e9935ce9bbad7791cbbcd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 15 Jul 2002 10:35:28 +0000 Subject: updated the 3.0 branch from the head branch - ready for alpha18 (This used to be commit 03ac082dcb375b6f3ca3d810a6a6367542bc23ce) --- source3/libads/ads_struct.c | 28 +- source3/libads/disp_sec.c | 20 +- source3/libads/kerberos.c | 155 ++-------- source3/libads/ldap.c | 679 +++++++++++++++++++++++------------------- source3/libads/ldap_printer.c | 73 +++-- source3/libads/ldap_user.c | 52 +++- source3/libads/sasl.c | 3 +- 7 files changed, 510 insertions(+), 500 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index 489f301ae2..638dc0b22e 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -81,7 +81,8 @@ static char *find_ldap_server(ADS_STRUCT *ads) char *list = NULL; struct in_addr ip; - if (ads->realm && + if (ads->realm && + strcasecmp(ads->workgroup, lp_workgroup()) == 0 && ldap_domain2hostlist(ads->realm, &list) == LDAP_SUCCESS) { char *p; p = strchr(list, ':'); @@ -90,7 +91,12 @@ static char *find_ldap_server(ADS_STRUCT *ads) } /* get desperate, find the domain controller IP */ - if (resolve_name(lp_workgroup(), &ip, 0x1B)) { + if (resolve_name(ads->workgroup, &ip, 0x1B)) { + return strdup(inet_ntoa(ip)); + } + + /* or a BDC ... */ + if (resolve_name(ads->workgroup, &ip, 0x1C)) { return strdup(inet_ntoa(ip)); } @@ -115,6 +121,7 @@ static char *find_ldap_server(ADS_STRUCT *ads) initialise a ADS_STRUCT, ready for some ads_ ops */ ADS_STRUCT *ads_init(const char *realm, + const char *workgroup, const char *ldap_server, const char *bind_path, const char *password) @@ -124,7 +131,12 @@ ADS_STRUCT *ads_init(const char *realm, ads = (ADS_STRUCT *)smb_xmalloc(sizeof(*ads)); ZERO_STRUCTP(ads); + if (!workgroup) { + workgroup = lp_workgroup(); + } + ads->realm = realm? strdup(realm) : NULL; + ads->workgroup = strdup(workgroup); ads->ldap_server = ldap_server? strdup(ldap_server) : NULL; ads->bind_path = bind_path? strdup(bind_path) : NULL; ads->ldap_port = LDAP_PORT; @@ -140,8 +152,10 @@ ADS_STRUCT *ads_init(const char *realm, ads->bind_path = ads_build_dn(ads->realm); } if (!ads->ldap_server) { - ads->ldap_server = strdup(lp_ads_server()); - if (!ads->ldap_server[0]) { + if (strcasecmp(ads->workgroup, lp_workgroup()) == 0) { + ads->ldap_server = strdup(lp_ads_server()); + } + if (!ads->ldap_server || !ads->ldap_server[0]) { ads->ldap_server = find_ldap_server(ads); } } @@ -153,6 +167,12 @@ ADS_STRUCT *ads_init(const char *realm, return ads; } +/* a simpler ads_init() interface using all defaults */ +ADS_STRUCT *ads_init_simple(void) +{ + return ads_init(NULL, NULL, NULL, NULL, NULL); +} + /* free the memory used by the ADS structure initialized with 'ads_init(...)' */ diff --git a/source3/libads/disp_sec.c b/source3/libads/disp_sec.c index ab8ceecb0c..a930fd6fe0 100644 --- a/source3/libads/disp_sec.c +++ b/source3/libads/disp_sec.c @@ -52,7 +52,7 @@ static struct perm_mask_str { }; /* convert a security permissions into a string */ -void ads_disp_perms(uint32 type) +static void ads_disp_perms(uint32 type) { int i = 0; int j = 0; @@ -82,20 +82,8 @@ void ads_disp_perms(uint32 type) puts(""); } -/* Check if ACE has OBJECT type */ -BOOL ads_ace_object(uint8 type) -{ - if (type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT || - type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT || - type == SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT || - type == SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT) { - return True; - } - return False; -} - /* display ACE */ -void ads_disp_ace(SEC_ACE *sec_ace) +static void ads_disp_ace(SEC_ACE *sec_ace) { char *access_type = "UNKNOWN"; @@ -123,7 +111,7 @@ void ads_disp_ace(SEC_ACE *sec_ace) } else if (sec_ace->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT) { access_type = "ALLOWED OBJECT"; } else if (sec_ace->type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT) { - access_type = "DEINED OBJECT"; + access_type = "DENIED OBJECT"; } else if (sec_ace->type == SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT) { access_type = "AUDIT OBJECT"; } @@ -135,7 +123,7 @@ void ads_disp_ace(SEC_ACE *sec_ace) } /* display ACL */ -void ads_disp_acl(SEC_ACL *sec_acl, char *type) +static void ads_disp_acl(SEC_ACL *sec_acl, char *type) { if (!sec_acl) printf("------- (%s) ACL not present\n", type); diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 194a71275e..1ba5d978e8 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -24,6 +24,28 @@ #ifdef HAVE_KRB5 +/* + we use a prompter to avoid a crash bug in the kerberos libs when + dealing with empty passwords + this prompter is just a string copy ... +*/ +static krb5_error_code +kerb_prompter(krb5_context ctx, void *data, + const char *name, + const char *banner, + int num_prompts, + krb5_prompt prompts[]) +{ + if (num_prompts == 0) return 0; + + memset(prompts[0].reply->data, 0, prompts[0].reply->length); + if (prompts[0].reply->length > 0) { + strncpy(prompts[0].reply->data, data, prompts[0].reply->length-1); + prompts[0].reply->length = strlen(prompts[0].reply->data); + } + return 0; +} + /* simulate a kinit, putting the tgt in the default cache location remus@snapserver.com @@ -36,11 +58,6 @@ int kerberos_kinit_password(const char *principal, const char *password) krb5_principal me; krb5_creds my_creds; - if (! *password) { - /* kerberos dies on an empty password! */ - return KRB5_PARSE_MALFORMED; - } - if ((code = krb5_init_context(&ctx))) return code; @@ -54,8 +71,9 @@ int kerberos_kinit_password(const char *principal, const char *password) return code; } - if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, (char*)password, NULL, - NULL, 0, NULL, NULL))) { + if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, NULL, + kerb_prompter, + password, 0, NULL, NULL))) { krb5_free_principal(ctx, me); krb5_free_context(ctx); return code; @@ -111,128 +129,5 @@ int ads_kinit_password(ADS_STRUCT *ads) return ret; } -/* - verify an incoming ticket and parse out the principal name and - authorization_data if available -*/ -NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, - char **principal, DATA_BLOB *auth_data) -{ - krb5_context context; - krb5_auth_context auth_context = NULL; - krb5_keytab keytab = NULL; - krb5_data packet; - krb5_ticket *tkt = NULL; - krb5_data salt; - krb5_encrypt_block eblock; - int ret; - krb5_keyblock * key; - krb5_principal host_princ; - char *host_princ_s; - extern pstring global_myname; - fstring myname; - char *password_s; - krb5_data password; - - if (!secrets_init()) { - DEBUG(1,("secrets_init failed\n")); - return NT_STATUS_LOGON_FAILURE; - } - - password_s = secrets_fetch_machine_password(); - if (!password_s) { - DEBUG(1,("failed to fetch machine password\n")); - return NT_STATUS_LOGON_FAILURE; - } - - password.data = password_s; - password.length = strlen(password_s); - - ret = krb5_init_context(&context); - if (ret) { - DEBUG(1,("krb5_init_context failed (%s)\n", error_message(ret))); - return NT_STATUS_LOGON_FAILURE; - } - - ret = krb5_set_default_realm(context, ads->realm); - if (ret) { - DEBUG(1,("krb5_set_default_realm failed (%s)\n", error_message(ret))); - ads_destroy(&ads); - return NT_STATUS_LOGON_FAILURE; - } - - /* this whole process is far more complex than I would - like. We have to go through all this to allow us to store - the secret internally, instead of using /etc/krb5.keytab */ - ret = krb5_auth_con_init(context, &auth_context); - if (ret) { - DEBUG(1,("krb5_auth_con_init failed (%s)\n", error_message(ret))); - return NT_STATUS_LOGON_FAILURE; - } - - fstrcpy(myname, global_myname); - strlower(myname); - asprintf(&host_princ_s, "HOST/%s@%s", myname, lp_realm()); - ret = krb5_parse_name(context, host_princ_s, &host_princ); - if (ret) { - DEBUG(1,("krb5_parse_name(%s) failed (%s)\n", host_princ_s, error_message(ret))); - return NT_STATUS_LOGON_FAILURE; - } - - ret = krb5_principal2salt(context, host_princ, &salt); - if (ret) { - DEBUG(1,("krb5_principal2salt failed (%s)\n", error_message(ret))); - return NT_STATUS_LOGON_FAILURE; - } - - if (!(key = (krb5_keyblock *)malloc(sizeof(*key)))) { - return NT_STATUS_NO_MEMORY; - } - - krb5_use_enctype(context, &eblock, ENCTYPE_DES_CBC_MD5); - - ret = krb5_string_to_key(context, &eblock, key, &password, &salt); - if (ret) { - DEBUG(1,("krb5_string_to_key failed (%s)\n", error_message(ret))); - return NT_STATUS_LOGON_FAILURE; - } - - krb5_auth_con_setuseruserkey(context, auth_context, key); - - packet.length = ticket->length; - packet.data = (krb5_pointer)ticket->data; - -#if 0 - file_save("/tmp/ticket.dat", ticket->data, ticket->length); -#endif - - if ((ret = krb5_rd_req(context, &auth_context, &packet, - NULL, keytab, NULL, &tkt))) { - DEBUG(3,("krb5_rd_req with auth failed (%s)\n", - error_message(ret))); - return NT_STATUS_LOGON_FAILURE; - } - - if (tkt->enc_part2) { - *auth_data = data_blob(tkt->enc_part2->authorization_data[0]->contents, - tkt->enc_part2->authorization_data[0]->length); - } - -#if 0 - if (tkt->enc_part2) { - file_save("/tmp/authdata.dat", - tkt->enc_part2->authorization_data[0]->contents, - tkt->enc_part2->authorization_data[0]->length); - } -#endif - - if ((ret = krb5_unparse_name(context, tkt->enc_part2->client, principal))) { - DEBUG(3,("krb5_unparse_name failed (%s)\n", - error_message(ret))); - return NT_STATUS_LOGON_FAILURE; - } - - return NT_STATUS_OK; -} #endif diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index e2e351bd4b..9d15c4e33c 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -30,6 +30,11 @@ * * The routines contained here should do the necessary ldap calls for * ads setups. + * + * Important note: attribute names passed into ads_ routines must + * already be in UTF-8 format. We do not convert them because in almost + * all cases, they are just ascii (which is represented with the same + * codepoints in UTF-8). This may have to change at some point **/ /** @@ -45,10 +50,38 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) ads->last_attempt = time(NULL); - ads->ld = ldap_open(ads->ldap_server, ads->ldap_port); + ads->ld = NULL; + + if (ads->ldap_server) { + ads->ld = ldap_open(ads->ldap_server, ads->ldap_port); + } + + /* if that failed then try each of the BDC's in turn */ + if (!ads->ld) { + struct in_addr *ip_list; + int count; + + if (get_dc_list(False, ads->workgroup, &ip_list, &count)) { + int i; + for (i=0;ild = ldap_open(inet_ntoa(ip_list[i]), + ads->ldap_port); + if (ads->ld) break; + } + if (ads->ld) { + SAFE_FREE(ads->ldap_server); + ads->ldap_server = strdup(inet_ntoa(ip_list[i])); + } + free(ip_list); + } + } + if (!ads->ld) { return ADS_ERROR_SYSTEM(errno); } + + DEBUG(3,("Connected to LDAP server %s\n", ads->ldap_server)); + status = ads_server_info(ads); if (!ADS_ERR_OK(status)) { DEBUG(1,("Failed to get ldap server info\n")); @@ -76,6 +109,81 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) return ads_sasl_bind(ads); } +/* + Duplicate a struct berval into talloc'ed memory + */ +static struct berval *dup_berval(TALLOC_CTX *ctx, const struct berval *in_val) +{ + struct berval *value; + + if (!in_val) return NULL; + + value = talloc_zero(ctx, sizeof(struct berval)); + if (in_val->bv_len == 0) return value; + + value->bv_len = in_val->bv_len; + value->bv_val = talloc_memdup(ctx, in_val->bv_val, in_val->bv_len); + return value; +} + +/* + Make a values list out of an array of (struct berval *) + */ +static struct berval **ads_dup_values(TALLOC_CTX *ctx, + const struct berval **in_vals) +{ + struct berval **values; + int i; + + if (!in_vals) return NULL; + for (i=0; in_vals[i]; i++); /* count values */ + values = (struct berval **) talloc_zero(ctx, + (i+1)*sizeof(struct berval *)); + if (!values) return NULL; + + for (i=0; in_vals[i]; i++) { + values[i] = dup_berval(ctx, in_vals[i]); + } + return values; +} + +/* + UTF8-encode a values list out of an array of (char *) + */ +static char **ads_push_strvals(TALLOC_CTX *ctx, const char **in_vals) +{ + char **values; + int i; + + if (!in_vals) return NULL; + for (i=0; in_vals[i]; i++); /* count values */ + values = (char ** ) talloc_zero(ctx, (i+1)*sizeof(char *)); + if (!values) return NULL; + + for (i=0; in_vals[i]; i++) { + push_utf8_talloc(ctx, (void **) &values[i], in_vals[i]); + } + return values; +} + +/* + Pull a (char *) array out of a UTF8-encoded values list + */ +static char **ads_pull_strvals(TALLOC_CTX *ctx, const char **in_vals) +{ + char **values; + int i; + + if (!in_vals) return NULL; + for (i=0; in_vals[i]; i++); /* count values */ + values = (char **) talloc_zero(ctx, (i+1)*sizeof(char *)); + if (!values) return NULL; + + for (i=0; in_vals[i]; i++) { + pull_utf8_talloc(ctx, (void **) &values[i], in_vals[i]); + } + return values; +} /** * Do a search with paged results. cookie must be null on the first @@ -84,8 +192,8 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) * @param ads connection to ads server * @param bind_path Base dn for the search * @param scope Scope of search (LDAP_BASE | LDAP_ONE | LDAP_SUBTREE) - * @param exp Search expression - * @param attrs Attributes to retrieve + * @param exp Search expression - specified in local charset + * @param attrs Attributes to retrieve - specified in utf8 or ascii * @param res ** which will contain results - free res* with ads_msgfree() * @param count Number of entries retrieved on this page * @param cookie The paged results cookie to be returned on subsequent calls @@ -96,25 +204,46 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, const char **attrs, void **res, int *count, void **cookie) { - int rc; - int version; - LDAPControl PagedResults; - LDAPControl NoReferrals; + int rc, i, version; + char *utf8_exp, *utf8_path, **search_attrs; + LDAPControl PagedResults, NoReferrals, *controls[3], **rcontrols; BerElement *cookie_be = NULL; struct berval *cookie_bv= NULL; - LDAPControl *controls[3]; - LDAPControl **rcontrols; - int i; + TALLOC_CTX *ctx; *res = NULL; - ldap_get_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); + if (!(ctx = talloc_init())) + return ADS_ERROR(LDAP_NO_MEMORY); - /* Paged results only available on ldap v3 or later, so check - version first before using, since at connect time we're - only v2. Not sure exactly why... */ - if (version < LDAP_VERSION3) - return ADS_ERROR(LDAP_NOT_SUPPORTED); + /* 0 means the conversion worked but the result was empty + so we only fail if it's negative. In any case, it always + at least nulls out the dest */ + if ((push_utf8_talloc(ctx, (void **) &utf8_exp, exp) < 0) || + (push_utf8_talloc(ctx, (void **) &utf8_path, bind_path) < 0)) { + rc = LDAP_NO_MEMORY; + goto done; + } + + if (!attrs || !(*attrs)) + search_attrs = NULL; + else { + /* This would be the utf8-encoded version...*/ + /* if (!(search_attrs = ads_push_strvals(ctx, attrs))) */ + if (!(str_list_copy(&search_attrs, (char **) attrs))) + { + rc = LDAP_NO_MEMORY; + goto done; + } + } + + + /* Paged results only available on ldap v3 or later */ + ldap_get_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); + if (version < LDAP_VERSION3) { + rc = LDAP_NOT_SUPPORTED; + goto done; + } cookie_be = ber_alloc_t(LBER_USE_DER); if (cookie && *cookie) { @@ -143,33 +272,32 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, *res = NULL; /* we need to disable referrals as the openldap libs don't - seem to handle them correctly. They result in the result - record containing the server control being removed from the - result list (tridge) + handle them and paged results at the same time. Using them + together results in the result record containing the server + page control being removed from the result list (tridge/jmcd) leaving this in despite the control that says don't generate referrals, in case the server doesn't support it (jmcd) */ ldap_set_option(ads->ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF); - rc = ldap_search_ext_s(ads->ld, bind_path, scope, exp, - (char **) attrs, 0, controls, NULL, - NULL, LDAP_NO_LIMIT, - (LDAPMessage **)res); + rc = ldap_search_ext_s(ads->ld, utf8_path, scope, utf8_exp, + search_attrs, 0, controls, + NULL, NULL, LDAP_NO_LIMIT, (LDAPMessage **)res); ber_free(cookie_be, 1); ber_bvfree(cookie_bv); if (rc) { DEBUG(3,("ldap_search_ext_s(%s) -> %s\n", exp, ldap_err2string(rc))); - return ADS_ERROR(rc); + goto done; } rc = ldap_parse_result(ads->ld, *res, NULL, NULL, NULL, NULL, &rcontrols, 0); if (!rcontrols) { - return ADS_ERROR(rc); + goto done; } for (i=0; rcontrols[i]; i++) { @@ -189,7 +317,12 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, } } ldap_controls_free(rcontrols); - + +done: + talloc_destroy(ctx); + /* if/when we decide to utf8-encode attrs, take out this next line */ + str_list_free(&search_attrs); + return ADS_ERROR(rc); } @@ -234,7 +367,6 @@ ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, next = ads_next_entry(ads, msg); ldap_add_result_entry((LDAPMessage **)res, msg); } - /* note that we do not free res2, as the memory is now part of the main returned list */ } @@ -248,15 +380,15 @@ ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, * @param ads connection to ads server * @param bind_path Base dn for the search * @param scope Scope of search (LDAP_BASE | LDAP_ONE | LDAP_SUBTREE) - * @param exp Search expression - * @param attrs Attributes to retrieve + * @param exp Search expression - specified in local charset + * @param attrs Attributes to retrieve - specified in UTF-8 or ascii * @param fn Function which takes attr name, values list, and data_area * @param data_area Pointer which is passed to function on each call * @return status of search **/ ADS_STATUS ads_do_search_all_fn(ADS_STRUCT *ads, const char *bind_path, int scope, const char *exp, const char **attrs, - void(*fn)(char *, void **, void *), + BOOL(*fn)(char *, void **, void *), void *data_area) { void *cookie = NULL; @@ -301,14 +433,42 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, { struct timeval timeout; int rc; + char *utf8_exp, *utf8_path, **search_attrs = NULL; + TALLOC_CTX *ctx; + + if (!(ctx = talloc_init())) + return ADS_ERROR(LDAP_NO_MEMORY); + + /* 0 means the conversion worked but the result was empty + so we only fail if it's negative. In any case, it always + at least nulls out the dest */ + if ((push_utf8_talloc(ctx, (void **) &utf8_exp, exp) < 0) || + (push_utf8_talloc(ctx, (void **) &utf8_path, bind_path) < 0)) { + rc = LDAP_NO_MEMORY; + goto done; + } + + if (!attrs || !(*attrs)) + search_attrs = NULL; + else { + /* This would be the utf8-encoded version...*/ + /* if (!(search_attrs = ads_push_strvals(ctx, attrs))) */ + if (!(str_list_copy(&search_attrs, (char **) attrs))) + { + rc = LDAP_NO_MEMORY; + goto done; + } + } timeout.tv_sec = ADS_SEARCH_TIMEOUT; timeout.tv_usec = 0; *res = NULL; - rc = ldap_search_ext_s(ads->ld, - bind_path, scope, - exp, (char **) attrs, 0, NULL, NULL, + /* see the note in ads_do_paged_search - we *must* disable referrals */ + ldap_set_option(ads->ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF); + + rc = ldap_search_ext_s(ads->ld, utf8_path, scope, utf8_exp, + search_attrs, 0, NULL, NULL, &timeout, LDAP_NO_LIMIT, (LDAPMessage **)res); if (rc == LDAP_SIZELIMIT_EXCEEDED) { @@ -316,6 +476,10 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, rc = 0; } + done: + talloc_destroy(ctx); + /* if/when we decide to utf8-encode attrs, take out this next line */ + str_list_free(&search_attrs); return ADS_ERROR(rc); } /** @@ -367,8 +531,7 @@ void ads_msgfree(ADS_STRUCT *ads, void *msg) **/ void ads_memfree(ADS_STRUCT *ads, void *mem) { - if (!mem) return; - ldap_memfree(mem); + SAFE_FREE(mem); } /** @@ -379,7 +542,12 @@ void ads_memfree(ADS_STRUCT *ads, void *mem) **/ char *ads_get_dn(ADS_STRUCT *ads, void *res) { - return ldap_get_dn(ads->ld, res); + char *utf8_dn, *unix_dn; + + utf8_dn = ldap_get_dn(ads->ld, res); + pull_utf8_allocate((void **) &unix_dn, utf8_dn); + ldap_memfree(utf8_dn); + return unix_dn; } /** @@ -403,25 +571,6 @@ ADS_STATUS ads_find_machine_acct(ADS_STRUCT *ads, void **res, const char *host) return status; } -/* - duplicate an already-assembled list of values so that it can be - freed as part of the standard msgfree call -*/ -static char **ads_dup_values(TALLOC_CTX *ctx, char **values) -{ - char **newvals; - int i; -#define ADS_MAX_NUM_VALUES 32 - - for (i=0; values[i] && imod_type = name; + modlist[curmod]->mod_type = talloc_strdup(ctx, name); if (mod_op & LDAP_MOD_BVALUES) modlist[curmod]->mod_bvalues = (struct berval **) values; else - modlist[curmod]->mod_values = values; + modlist[curmod]->mod_values = (char **) values; modlist[curmod]->mod_op = mod_op; return ADS_ERROR(LDAP_SUCCESS); } /** - * Add an already-constructed list of values to a mod list for an ADD + * Add a single string value to a mod list * @param ctx An initialized TALLOC_CTX * @param mods An initialized ADS_MODLIST * @param name The attribute name to add - * @param values Constructed values list to add + * @param val The value to add - NULL means DELETE * @return ADS STATUS indicating success of add **/ -ADS_STATUS ads_mod_add_list(TALLOC_CTX *ctx, ADS_MODLIST *mods, - char *name, char **values) -{ - char **newvals = ads_dup_values(ctx, values); - if (newvals) - return ads_modlist_add(ctx, mods, LDAP_MOD_ADD, name, newvals); - else - return ADS_ERROR(LDAP_NO_MEMORY); -} - -/** - * Add an already-constructed list of values to a mod list for a REPLACE - * @param ctx An initialized TALLOC_CTX - * @param mods An initialized ADS_MODLIST - * @param name The attribute name to add - * @param values Constructed values list to add - * @return ADS STATUS indicating success of add - **/ -ADS_STATUS ads_mod_repl_list(TALLOC_CTX *ctx, ADS_MODLIST *mods, - char *name, char **values) +ADS_STATUS ads_mod_str(TALLOC_CTX *ctx, ADS_MODLIST *mods, + const char *name, const char *val) { - char **newvals; - if (values && *values) { - if (!(newvals = ads_dup_values(ctx, values))) - return ADS_ERROR(LDAP_NO_MEMORY); - else - return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE, - name, newvals); - } - else + const char *values[2] = {val, NULL}; + if (!val) return ads_modlist_add(ctx, mods, LDAP_MOD_DELETE, name, NULL); + return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE, name, + (const void **) values); } /** - * Add any number of string values to a mod list - for ADD or REPLACE - * @param ctx An initialized TALLOC_CTX - * @param mods An initialized ADS_MODLIST - * @param mod_op Operation to perform (LDAP_MOD_ADD | LDAP_MOD_REPLACE) - * @param name The attribute name to add - * @param ... Any number of values, in (char *) form - * @return ADS STATUS indicating success of add - **/ -ADS_STATUS ads_mod_add_var(TALLOC_CTX *ctx, ADS_MODLIST *mods, - int mod_op, const char *name, ...) -{ - va_list ap; - int num_vals, i, do_op; - char *value, **values; - - /* count the number of values */ - va_start(ap, name); - for (num_vals=0; va_arg(ap, char *); num_vals++); - va_end(ap); - - if (num_vals) { - if (!(values = talloc_zero(ctx, sizeof(char *)*(num_vals+1)))) - return ADS_ERROR(LDAP_NO_MEMORY); - va_start(ap, name); - for (i=0; (value = (char *) va_arg(ap, char *)) && - i < num_vals; i++) - values[i] = value; - va_end(ap); - values[i] = NULL; - do_op = mod_op; - } else { - do_op = LDAP_MOD_DELETE; - values = NULL; - } - return ads_modlist_add(ctx, mods, do_op, name, values); -} - -/** - * Add any number of ber values to a mod list - for ADD or REPLACE + * Add an array of string values to a mod list * @param ctx An initialized TALLOC_CTX * @param mods An initialized ADS_MODLIST - * @param mod_op Operation to perform (LDAP_MOD_ADD | LDAP_MOD_REPLACE) * @param name The attribute name to add - * @param ... Any number of values, in (struct berval *) form + * @param vals The array of string values to add - NULL means DELETE * @return ADS STATUS indicating success of add **/ -ADS_STATUS ads_mod_add_ber(TALLOC_CTX *ctx, ADS_MODLIST *mods, - int mod_op, const char *name, ...) +ADS_STATUS ads_mod_strlist(TALLOC_CTX *ctx, ADS_MODLIST *mods, + const char *name, const char **vals) { - va_list ap; - int num_vals, i, do_op; - char *value, **values; - - /* count the number of values */ - va_start(ap, name); - for (num_vals=0; va_arg(ap, struct berval *); num_vals++); - va_end(ap); - - if (num_vals) { - if (!(values = talloc_zero(ctx, sizeof(struct berval) * - (num_vals + 1)))) - return ADS_ERROR(LDAP_NO_MEMORY); - va_start(ap, name); - for (i=0; (value = (char *) va_arg(ap, char *)) && - i < num_vals; i++) - values[i] = value; - va_end(ap); - values[i] = NULL; - do_op = mod_op; - } else { - do_op = LDAP_MOD_DELETE; - values = NULL; - } - do_op |= LDAP_MOD_BVALUES; - return ads_modlist_add(ctx, mods, do_op, name, values); -} - -/** - * Add a single string value to a mod list - for REPLACE - * @param ctx An initialized TALLOC_CTX - * @param mods An initialized ADS_MODLIST - * @param name The attribute name to replace - * @param val The value to add - * @return ADS STATUS indicating success of add - **/ -ADS_STATUS ads_mod_repl(TALLOC_CTX *ctx, ADS_MODLIST *mods, - char *name, char *val) -{ - if (val) - return ads_mod_add_var(ctx, mods, LDAP_MOD_REPLACE, - name, val, NULL); - else - return ads_mod_add_var(ctx, mods, LDAP_MOD_DELETE, name, NULL); -} - -/** - * Add a single string value to a mod list - for ADD - * @param ctx An initialized TALLOC_CTX - * @param mods An initialized ADS_MODLIST - * @param name The attribute name to add - * @param val The value to add - * @return ADS STATUS indicating success of add - **/ -ADS_STATUS ads_mod_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, - const char *name, const char *val) -{ - return ads_mod_add_var(ctx, mods, LDAP_MOD_ADD, name, val, NULL); + if (!vals) + return ads_modlist_add(ctx, mods, LDAP_MOD_DELETE, name, NULL); + return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE, + name, (const void **) vals); } /** - * Add a single berval value to a mod list - for ADD + * Add a single ber-encoded value to a mod list * @param ctx An initialized TALLOC_CTX * @param mods An initialized ADS_MODLIST * @param name The attribute name to add - * @param size The size of of the value - * @param val The value to add - * @return ADS STATUS indicating success of add - **/ -ADS_STATUS ads_mod_add_len(TALLOC_CTX *ctx, ADS_MODLIST *mods, - char *name, size_t size, char *val) -{ - struct berval *bval = NULL; - - if (!(bval = talloc_zero(ctx, sizeof(struct berval *)))) - return ADS_ERROR(LDAP_NO_MEMORY); - if (!(bval->bv_val = talloc_zero(ctx, sizeof(char *)))) - return ADS_ERROR(LDAP_NO_MEMORY); - - bval->bv_val = val; - bval->bv_len = size; - return ads_mod_add_ber(ctx, mods, LDAP_MOD_ADD, name, bval, NULL); -} - -/** - * Add a single berval value to a mod list - for REPLACE - * @param ctx An initialized TALLOC_CTX - * @param mods An initialized ADS_MODLIST - * @param name The attribute name to replace - * @param size The size of of the value - * @param val The value to add + * @param val The value to add - NULL means DELETE * @return ADS STATUS indicating success of add **/ -ADS_STATUS ads_mod_repl_len(TALLOC_CTX *ctx, ADS_MODLIST *mods, - const char *name, size_t size, char *val) +static ADS_STATUS ads_mod_ber(TALLOC_CTX *ctx, ADS_MODLIST *mods, + const char *name, const struct berval *val) { - struct berval *bval = NULL; - - if (!(bval = talloc_zero(ctx, sizeof(struct berval *)))) - return ADS_ERROR(LDAP_NO_MEMORY); - + const struct berval *values[2] = {val, NULL}; if (!val) - return ads_mod_add_ber(ctx, mods, LDAP_MOD_DELETE, name, NULL); - else { - if (!(bval->bv_val = talloc_zero(ctx, sizeof(char *)))) - return ADS_ERROR(LDAP_NO_MEMORY); - bval->bv_val = val; - bval->bv_len = size; - return ads_mod_add_ber(ctx, mods, LDAP_MOD_REPLACE, name, - bval, NULL); - } + return ads_modlist_add(ctx, mods, LDAP_MOD_DELETE, name, NULL); + return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE|LDAP_MOD_BVALUES, + name, (const void **) values); } /** @@ -688,6 +701,7 @@ ADS_STATUS ads_mod_repl_len(TALLOC_CTX *ctx, ADS_MODLIST *mods, ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, ADS_MODLIST mods) { int ret,i; + char *utf8_dn = NULL; /* this control is needed to modify that contains a currently non-existent attribute (but allowable for the object) to run @@ -701,12 +715,15 @@ ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, ADS_MODLIST mods) controls[0] = &PermitModify; controls[1] = NULL; + push_utf8_allocate((void **) &utf8_dn, mod_dn); + /* find the end of the list, marked by NULL or -1 */ for(i=0;(mods[i]!=0)&&(mods[i]!=(LDAPMod *) -1);i++); /* make sure the end of the list is NULL */ mods[i] = NULL; - ret = ldap_modify_ext_s(ads->ld, mod_dn, (LDAPMod **) mods, - controls, NULL); + ret = ldap_modify_ext_s(ads->ld, utf8_dn ? utf8_dn : mod_dn, + (LDAPMod **) mods, controls, NULL); + SAFE_FREE(utf8_dn); return ADS_ERROR(ret); } @@ -719,14 +736,19 @@ ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, ADS_MODLIST mods) **/ ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ADS_MODLIST mods) { - int i; + int ret, i; + char *utf8_dn = NULL; + push_utf8_allocate((void **) &utf8_dn, new_dn); + /* find the end of the list, marked by NULL or -1 */ for(i=0;(mods[i]!=0)&&(mods[i]!=(LDAPMod *) -1);i++); /* make sure the end of the list is NULL */ mods[i] = NULL; - return ADS_ERROR(ldap_add_s(ads->ld, new_dn, mods)); + ret = ldap_add_s(ads->ld, utf8_dn ? utf8_dn : new_dn, mods); + SAFE_FREE(utf8_dn); + return ADS_ERROR(ret); } /** @@ -737,7 +759,11 @@ ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ADS_MODLIST mods) **/ ADS_STATUS ads_del_dn(ADS_STRUCT *ads, char *del_dn) { - return ADS_ERROR(ldap_delete(ads->ld, del_dn)); + int ret; + char *utf8_dn = NULL; + push_utf8_allocate((void **) &utf8_dn, del_dn); + ret = ldap_delete(ads->ld, utf8_dn ? utf8_dn : del_dn); + return ADS_ERROR(ret); } /** @@ -769,6 +795,8 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, char *ou_str; TALLOC_CTX *ctx; ADS_MODLIST mods; + const char *objectClass[] = {"top", "person", "organizationalPerson", + "user", "computer", NULL}; if (!(ctx = talloc_init_named("machine_account"))) return ADS_ERROR(LDAP_NO_MEMORY); @@ -796,17 +824,15 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, if (!(mods = ads_init_mods(ctx))) goto done; - ads_mod_add(ctx, &mods, "cn", hostname); - ads_mod_add(ctx, &mods, "sAMAccountName", samAccountName); - ads_mod_add_var(ctx, &mods, LDAP_MOD_ADD, "objectClass", - "top", "person", "organizationalPerson", - "user", "computer", NULL); - ads_mod_add(ctx, &mods, "userPrincipalName", host_upn); - ads_mod_add(ctx, &mods, "servicePrincipalName", host_spn); - ads_mod_add(ctx, &mods, "dNSHostName", hostname); - ads_mod_add(ctx, &mods, "userAccountControl", controlstr); - ads_mod_add(ctx, &mods, "operatingSystem", "Samba"); - ads_mod_add(ctx, &mods, "operatingSystemVersion", VERSION); + ads_mod_str(ctx, &mods, "cn", hostname); + ads_mod_str(ctx, &mods, "sAMAccountName", samAccountName); + ads_mod_strlist(ctx, &mods, "objectClass", objectClass); + ads_mod_str(ctx, &mods, "userPrincipalName", host_upn); + ads_mod_str(ctx, &mods, "servicePrincipalName", host_spn); + ads_mod_str(ctx, &mods, "dNSHostName", hostname); + ads_mod_str(ctx, &mods, "userAccountControl", controlstr); + ads_mod_str(ctx, &mods, "operatingSystem", "Samba"); + ads_mod_str(ctx, &mods, "operatingSystemVersion", VERSION); ads_gen_add(ads, new_dn, mods); ret = ads_set_machine_sd(ads, hostname, new_dn); @@ -877,11 +903,11 @@ static void dump_sd(const char *filed, struct berval **values) /* dump a string result from ldap */ -static void dump_string(const char *field, struct berval **values) +static void dump_string(const char *field, char **values) { int i; for (i=0; values[i]; i++) { - printf("%s: %s\n", field, values[i]->bv_val); + printf("%s: %s\n", field, values[i]); } } @@ -890,33 +916,39 @@ static void dump_string(const char *field, struct berval **values) used for debugging */ -static void ads_dump_field(char *field, void **values, void *data_area) +static BOOL ads_dump_field(char *field, void **values, void *data_area) { struct { char *name; + BOOL string; void (*handler)(const char *, struct berval **); } handlers[] = { - {"objectGUID", dump_binary}, - {"nTSecurityDescriptor", dump_sd}, - {"objectSid", dump_sid}, - {NULL, NULL} + {"objectGUID", False, dump_binary}, + {"nTSecurityDescriptor", False, dump_sd}, + {"objectSid", False, dump_sid}, + {NULL, True, NULL} }; int i; if (!field) { /* must be end of an entry */ printf("\n"); - return; + return False; } for (i=0; handlers[i].name; i++) { if (StrCaseCmp(handlers[i].name, field) == 0) { + if (!values) /* first time, indicate string or not */ + return handlers[i].string; handlers[i].handler(field, (struct berval **) values); break; } } if (!handlers[i].name) { - dump_string(field, (struct berval **) values); + if (!values) /* first time, indicate string conversion */ + return True; + dump_string(field, (char **)values); } + return False; } /** @@ -943,62 +975,57 @@ void ads_dump(ADS_STRUCT *ads, void *res) * @param data_area user-defined area to pass to function **/ void ads_process_results(ADS_STRUCT *ads, void *res, - void(*fn)(char *, void **, void *), + BOOL(*fn)(char *, void **, void *), void *data_area) { void *msg; + TALLOC_CTX *ctx; + + if (!(ctx = talloc_init())) + return; for (msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) { - char *field; + char *utf8_field; BerElement *b; - for (field = ldap_first_attribute(ads->ld, (LDAPMessage *)msg, &b); - field; - field = ldap_next_attribute(ads->ld, (LDAPMessage *)msg, b)) { - struct berval **values; - - values = ldap_get_values_len(ads->ld, (LDAPMessage *)msg, field); - fn(field, (void **) values, data_area); - - ldap_value_free_len(values); - ldap_memfree(field); + for (utf8_field=ldap_first_attribute(ads->ld, + (LDAPMessage *)msg,&b); + utf8_field; + utf8_field=ldap_next_attribute(ads->ld, + (LDAPMessage *)msg,b)) { + struct berval **ber_vals; + char **str_vals, **utf8_vals; + char *field; + BOOL string; + + pull_utf8_talloc(ctx, (void **) &field, utf8_field); + string = fn(field, NULL, data_area); + + if (string) { + utf8_vals = ldap_get_values(ads->ld, + (LDAPMessage *)msg, field); + str_vals = ads_pull_strvals(ctx, + (const char **) utf8_vals); + fn(field, (void **) str_vals, data_area); + ldap_value_free(utf8_vals); + } else { + ber_vals = ldap_get_values_len(ads->ld, + (LDAPMessage *)msg, field); + fn(field, (void **) ber_vals, data_area); + + ldap_value_free_len(ber_vals); + } + ldap_memfree(utf8_field); } ber_free(b, 0); + talloc_destroy_pool(ctx); fn(NULL, NULL, data_area); /* completed an entry */ } + talloc_destroy(ctx); } -/** - * Walk through an entry, calling a function for each attribute found. - * The function receives a field name, a berval * array of values, - * and a data area passed through from the start. - * @param ads connection to ads server - * @param res Results to process - * @param fn Function for processing each result - * @param data_area user-defined area to pass to function - **/ -void ads_process_entry(ADS_STRUCT *ads, void *msg, - void(*fn)(ADS_STRUCT *, char *, void **, void *), - void *data_area) -{ - char *field; - BerElement *b; - - for (field = ldap_first_attribute(ads->ld, (LDAPMessage *)msg, &b); - field; - field = ldap_next_attribute(ads->ld, (LDAPMessage *)msg, b)) { - struct berval **values; - - values = ldap_get_values_len(ads->ld, (LDAPMessage *)msg, field); - fn(ads, field, (void **) values, data_area); - - ldap_value_free_len(values); - ldap_memfree(field); - } - ber_free(b, 0); -} /** * count how many replies are in a LDAPMessage * @param ads connection to ads server @@ -1110,6 +1137,7 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) char *exp = 0; size_t sd_size = 0; struct berval **bvals = 0; + struct berval bval = {0, NULL}; prs_struct ps; prs_struct ps_wire; @@ -1164,7 +1192,9 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) #endif if (!(mods = ads_init_mods(ctx))) return ADS_ERROR(LDAP_NO_MEMORY); - ads_mod_repl_len(ctx, &mods, attrs[0], sd_size, ps_wire.data_p); + bval.bv_len = sd_size; + bval.bv_val = prs_data_p(&ps_wire); + ads_mod_ber(ctx, &mods, attrs[0], &bval); ret = ads_gen_mod(ads, dn, mods); prs_mem_free(&ps); @@ -1201,7 +1231,11 @@ ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads, strlower(host); - asprintf(&principal, "%s@%s", host, ads->realm); + /* + we need to use the '$' form of the name here, as otherwise the + server might end up setting the password for a user instead + */ + asprintf(&principal, "%s$@%s", host, ads->realm); status = krb5_set_password(ads->kdc_server, principal, password); @@ -1246,17 +1280,58 @@ char *ads_pull_string(ADS_STRUCT *ads, { char **values; char *ret = NULL; + char *ux_string; + int rc; values = ldap_get_values(ads->ld, msg, field); if (!values) return NULL; if (values[0]) { - ret = talloc_strdup(mem_ctx, values[0]); + rc = pull_utf8_talloc(mem_ctx, (void **)&ux_string, + values[0]); + if (rc != -1) + ret = ux_string; + } ldap_value_free(values); return ret; } +/** + * pull an array of strings from a ADS result + * @param ads connection to ads server + * @param mem_ctx TALLOC_CTX to use for allocating result string + * @param msg Results of search + * @param field Attribute to retrieve + * @return Result strings in talloc context + **/ +char **ads_pull_strings(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, void *msg, const char *field) +{ + char **values; + char **ret = NULL; + int i, n; + + values = ldap_get_values(ads->ld, msg, field); + if (!values) return NULL; + + for (i=0;values[i];i++) /* noop */ ; + n = i; + + ret = talloc(mem_ctx, sizeof(char *) * (n+1)); + + for (i=0;ild, *res); + srv_cn = ldap_explode_dn(srv_dn, 1); ads_msgfree(ads, *res); - asprintf(&exp, "(printerName=%s)", printer); - status = ads_do_search(ads, srv_dn, LDAP_SCOPE_SUBTREE, - exp, attrs, res); + asprintf(&exp, "(cn=%s-%s)", srv_cn[0], printer); + status = ads_search(ads, res, exp, attrs); + ldap_memfree(srv_dn); + ldap_value_free(srv_cn); free(exp); return status; } @@ -68,33 +70,33 @@ ADS_STATUS ads_mod_printer_entry(ADS_STRUCT *ads, char *prt_dn, mods = ads_init_mods(ctx); /* add the attributes to the list - required ones first */ - ads_mod_repl(ctx, &mods, "printerName", prt->printerName); - ads_mod_repl(ctx, &mods, "serverName", prt->serverName); - ads_mod_repl(ctx, &mods, "shortServerName", prt->shortServerName); - ads_mod_repl(ctx, &mods, "uNCName", prt->uNCName); - ads_mod_repl(ctx, &mods, "versionNumber", prt->versionNumber); + ads_mod_str(ctx, &mods, "printerName", prt->printerName); + ads_mod_str(ctx, &mods, "serverName", prt->serverName); + ads_mod_str(ctx, &mods, "shortServerName", prt->shortServerName); + ads_mod_str(ctx, &mods, "uNCName", prt->uNCName); + ads_mod_str(ctx, &mods, "versionNumber", prt->versionNumber); /* now the optional ones */ - ads_mod_repl_list(ctx, &mods, "description", prt->description); - ads_mod_repl(ctx, &mods, "assetNumber",prt->assetNumber); - ads_mod_repl(ctx, &mods, "bytesPerMinute",prt->bytesPerMinute); - ads_mod_repl(ctx, &mods, "defaultPriority",prt->defaultPriority); - ads_mod_repl(ctx, &mods, "driverName", prt->driverName); - ads_mod_repl(ctx, &mods, "driverVersion",prt->driverVersion); - ads_mod_repl(ctx, &mods, "location", prt->location); - ads_mod_repl(ctx, &mods, "operatingSystem",prt->operatingSystem); - ads_mod_repl(ctx, &mods, "operatingSystemHotfix", + ads_mod_strlist(ctx, &mods, "description", prt->description); + ads_mod_str(ctx, &mods, "assetNumber",prt->assetNumber); + ads_mod_str(ctx, &mods, "bytesPerMinute",prt->bytesPerMinute); + ads_mod_str(ctx, &mods, "defaultPriority",prt->defaultPriority); + ads_mod_str(ctx, &mods, "driverName", prt->driverName); + ads_mod_str(ctx, &mods, "driverVersion",prt->driverVersion); + ads_mod_str(ctx, &mods, "location", prt->location); + ads_mod_str(ctx, &mods, "operatingSystem",prt->operatingSystem); + ads_mod_str(ctx, &mods, "operatingSystemHotfix", prt->operatingSystemHotfix); - ads_mod_repl(ctx, &mods, "operatingSystemServicePack", + ads_mod_str(ctx, &mods, "operatingSystemServicePack", prt->operatingSystemServicePack); - ads_mod_repl(ctx, &mods, "operatingSystemVersion", + ads_mod_str(ctx, &mods, "operatingSystemVersion", prt->operatingSystemVersion); - ads_mod_repl(ctx, &mods, "physicalLocationObject", + ads_mod_str(ctx, &mods, "physicalLocationObject", prt->physicalLocationObject); - ads_mod_repl_list(ctx, &mods, "portName", prt->portName); - ads_mod_repl(ctx, &mods, "printStartTime", prt->printStartTime); - ads_mod_repl(ctx, &mods, "printEndTime", prt->printEndTime); - ads_mod_repl_list(ctx, &mods, "printBinNames", prt->printBinNames); + ads_mod_strlist(ctx, &mods, "portName", prt->portName); + ads_mod_str(ctx, &mods, "printStartTime", prt->printStartTime); + ads_mod_str(ctx, &mods, "printEndTime", prt->printEndTime); + ads_mod_strlist(ctx, &mods, "printBinNames", prt->printBinNames); /*... and many others */ /* do the ldap modify */ @@ -124,12 +126,12 @@ static ADS_STATUS ads_add_printer_entry(ADS_STRUCT *ads, char *prt_dn, return ADS_ERROR(LDAP_NO_MEMORY); /* These are the fields a printQueue must contain */ - ads_mod_add(ctx, &mods, "uNCName", prt->uNCName); - ads_mod_add(ctx, &mods, "versionNumber", prt->versionNumber); - ads_mod_add(ctx, &mods, "serverName", prt->serverName); - ads_mod_add(ctx, &mods, "shortServerName", prt->shortServerName); - ads_mod_add(ctx, &mods, "printerName", prt->printerName); - ads_mod_add(ctx, &mods, "objectClass", "printQueue"); + ads_mod_str(ctx, &mods, "uNCName", prt->uNCName); + ads_mod_str(ctx, &mods, "versionNumber", prt->versionNumber); + ads_mod_str(ctx, &mods, "serverName", prt->serverName); + ads_mod_str(ctx, &mods, "shortServerName", prt->shortServerName); + ads_mod_str(ctx, &mods, "printerName", prt->printerName); + ads_mod_str(ctx, &mods, "objectClass", "printQueue"); status = ads_gen_add(ads, prt_dn, mods); @@ -157,14 +159,11 @@ ADS_STATUS ads_add_printer(ADS_STRUCT *ads, const ADS_PRINTER_ENTRY *prt) prt->shortServerName)); return status; } - host_dn = ldap_get_dn(ads->ld, res); + host_dn = ads_get_dn(ads, res); ads_msgfree(ads, res); - /* printer dn is cn=server-printer followed by host dn */ - asprintf(&prt_dn, "cn=%s-%s,%s", prt->shortServerName, - prt->printerName, host_dn); - - status = ads_search_dn(ads, &res, prt_dn, attrs); + ads_find_printer_on_server(ads, &res, prt->printerName, + prt->shortServerName); if (ADS_ERR_OK(status) && ads_count_replies(ads, res)) { DEBUG(1, ("ads_add_printer: printer %s already exists\n", diff --git a/source3/libads/ldap_user.c b/source3/libads/ldap_user.c index 13e68eb82e..b6e3d189c5 100644 --- a/source3/libads/ldap_user.c +++ b/source3/libads/ldap_user.c @@ -43,7 +43,9 @@ ADS_STATUS ads_add_user_acct(ADS_STRUCT *ads, const char *user, TALLOC_CTX *ctx; ADS_MODLIST mods; ADS_STATUS status; - char *upn, *new_dn, *name, *controlstr; + const char *upn, *new_dn, *name, *controlstr; + const char *objectClass[] = {"top", "person", "organizationalPerson", + "user", NULL}; if (fullname && *fullname) name = fullname; else name = user; @@ -63,14 +65,46 @@ ADS_STATUS ads_add_user_acct(ADS_STRUCT *ads, const char *user, if (!(mods = ads_init_mods(ctx))) goto done; - ads_mod_add(ctx, &mods, "cn", name); - ads_mod_add_var(ctx, &mods, LDAP_MOD_ADD, "objectClass", "top", - "person", "organizationalPerson", "user", NULL); - ads_mod_add(ctx, &mods, "userPrincipalName", upn); - ads_mod_add(ctx, &mods, "name", name); - ads_mod_add(ctx, &mods, "displayName", name); - ads_mod_add(ctx, &mods, "sAMAccountName", user); - ads_mod_add(ctx, &mods, "userAccountControl", controlstr); + ads_mod_str(ctx, &mods, "cn", name); + ads_mod_strlist(ctx, &mods, "objectClass", objectClass); + ads_mod_str(ctx, &mods, "userPrincipalName", upn); + ads_mod_str(ctx, &mods, "name", name); + ads_mod_str(ctx, &mods, "displayName", name); + ads_mod_str(ctx, &mods, "sAMAccountName", user); + ads_mod_str(ctx, &mods, "userAccountControl", controlstr); + status = ads_gen_add(ads, new_dn, mods); + + done: + talloc_destroy(ctx); + return status; +} + +ADS_STATUS ads_add_group_acct(ADS_STRUCT *ads, const char *group, + const char *comment) +{ + TALLOC_CTX *ctx; + ADS_MODLIST mods; + ADS_STATUS status; + char *new_dn; + const char *objectClass[] = {"top", "group", NULL}; + + if (!(ctx = talloc_init_named("ads_add_group_acct"))) + return ADS_ERROR(LDAP_NO_MEMORY); + + status = ADS_ERROR(LDAP_NO_MEMORY); + + if (!(new_dn = talloc_asprintf(ctx, "cn=%s,cn=Users,%s", group, + ads->bind_path))) + goto done; + if (!(mods = ads_init_mods(ctx))) + goto done; + + ads_mod_str(ctx, &mods, "cn", group); + ads_mod_strlist(ctx, &mods, "objectClass",objectClass); + ads_mod_str(ctx, &mods, "name", group); + if (comment) + ads_mod_str(ctx, &mods, "description", comment); + ads_mod_str(ctx, &mods, "sAMAccountName", group); status = ads_gen_add(ads, new_dn, mods); done: diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index eb29c71fce..1b55453cac 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -171,8 +171,7 @@ ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) *p++ = max_msg_size>>16; *p++ = max_msg_size>>8; *p++ = max_msg_size; - snprintf(p, strlen(ads->bind_path)+1, "dn:%s", ads->bind_path); - p += strlen(ads->bind_path); + snprintf(p, strlen(ads->bind_path)+4, "dn:%s", ads->bind_path); output_token.length = strlen(ads->bind_path) + 8; -- cgit From 29075c97d3b7111e2565ede1cd0f000fd2534375 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 20 Jul 2002 13:02:47 +0000 Subject: More fixes towards warnings on the IRIX compiler (and yes, some of these are real bugs) In particular, the samr code was doing an &foo of various types, to a function that assumed uint32. If time_t isn't 32 bits long, that broke. They are assignment compatible however, so use that and an intermediate variable. Andrew Bartlett (This used to be commit 30d0998c8c1a1d4de38ef0fbc83c2b763e05a3e6) --- source3/libads/ldap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 9d15c4e33c..f91ef4b8a0 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -230,7 +230,7 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, else { /* This would be the utf8-encoded version...*/ /* if (!(search_attrs = ads_push_strvals(ctx, attrs))) */ - if (!(str_list_copy(&search_attrs, (char **) attrs))) + if (!(str_list_copy(&search_attrs, attrs))) { rc = LDAP_NO_MEMORY; goto done; @@ -453,7 +453,7 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, else { /* This would be the utf8-encoded version...*/ /* if (!(search_attrs = ads_push_strvals(ctx, attrs))) */ - if (!(str_list_copy(&search_attrs, (char **) attrs))) + if (!(str_list_copy(&search_attrs, attrs))) { rc = LDAP_NO_MEMORY; goto done; -- cgit From 2edcc96c11c1f5c9294f1730973e7582b3a3acbd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 30 Jul 2002 13:27:42 +0000 Subject: a couple more minor tweaks. This now allows us to operate in ADS mode without any 'realm =' or 'ads server =' options at all, as long as DNS is working right. (This used to be commit d3fecdd04241ed7b9248e52415693cd54a1faecf) --- source3/libads/ads_struct.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index 638dc0b22e..0be79673a0 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -148,6 +148,12 @@ ADS_STRUCT *ads_init(const char *realm, SAFE_FREE(ads->realm); } } + + if (!ads->realm && strchr_m(ads->workgroup, '.')) { + /* the smb.conf has specified the realm in 'workgroup =' */ + ads->realm = strdup(ads->workgroup); + } + if (!ads->bind_path && ads->realm) { ads->bind_path = ads_build_dn(ads->realm); } -- cgit From 55c978d85ea9b2fbd3eeb597d4b383399c5106a7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 30 Jul 2002 15:34:10 +0000 Subject: net ads info now reports the IP of the LDAP server as well as its name - very useful in scripts (This used to be commit fc0d5479b575c1f495b9251413eed18ec1e37e02) --- source3/libads/ads_struct.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index 0be79673a0..af0b5d4143 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -162,6 +162,7 @@ ADS_STRUCT *ads_init(const char *realm, ads->ldap_server = strdup(lp_ads_server()); } if (!ads->ldap_server || !ads->ldap_server[0]) { + SAFE_FREE(ads->ldap_server); ads->ldap_server = find_ldap_server(ads); } } @@ -170,6 +171,11 @@ ADS_STRUCT *ads_init(const char *realm, ads->kdc_server = ads->ldap_server? strdup(ads->ldap_server) : NULL; } + if (ads->ldap_server) { + /* its very useful knowing the IP of the ldap server */ + ads->ldap_ip = *interpret_addr2(ads->ldap_server); + } + return ads; } -- cgit From 056f849f0c57636787800457d2d191aefacfac05 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 4 Aug 2002 01:16:37 +0000 Subject: Now that I got the function arguments sane, remove the silly (void **) casts from some of the callers. Andrew Bartlett (This used to be commit eb3354aa6c7293df9a728565a6774049b2e6d57f) --- source3/libads/ldap.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index f91ef4b8a0..1753d7d3ad 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -161,7 +161,7 @@ static char **ads_push_strvals(TALLOC_CTX *ctx, const char **in_vals) if (!values) return NULL; for (i=0; in_vals[i]; i++) { - push_utf8_talloc(ctx, (void **) &values[i], in_vals[i]); + push_utf8_talloc(ctx, &values[i], in_vals[i]); } return values; } @@ -180,7 +180,7 @@ static char **ads_pull_strvals(TALLOC_CTX *ctx, const char **in_vals) if (!values) return NULL; for (i=0; in_vals[i]; i++) { - pull_utf8_talloc(ctx, (void **) &values[i], in_vals[i]); + pull_utf8_talloc(ctx, &values[i], in_vals[i]); } return values; } @@ -219,8 +219,8 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, /* 0 means the conversion worked but the result was empty so we only fail if it's negative. In any case, it always at least nulls out the dest */ - if ((push_utf8_talloc(ctx, (void **) &utf8_exp, exp) < 0) || - (push_utf8_talloc(ctx, (void **) &utf8_path, bind_path) < 0)) { + if ((push_utf8_talloc(ctx, &utf8_exp, exp) < 0) || + (push_utf8_talloc(ctx, &utf8_path, bind_path) < 0)) { rc = LDAP_NO_MEMORY; goto done; } @@ -442,8 +442,8 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, /* 0 means the conversion worked but the result was empty so we only fail if it's negative. In any case, it always at least nulls out the dest */ - if ((push_utf8_talloc(ctx, (void **) &utf8_exp, exp) < 0) || - (push_utf8_talloc(ctx, (void **) &utf8_path, bind_path) < 0)) { + if ((push_utf8_talloc(ctx, &utf8_exp, exp) < 0) || + (push_utf8_talloc(ctx, &utf8_path, bind_path) < 0)) { rc = LDAP_NO_MEMORY; goto done; } @@ -999,7 +999,7 @@ void ads_process_results(ADS_STRUCT *ads, void *res, char *field; BOOL string; - pull_utf8_talloc(ctx, (void **) &field, utf8_field); + pull_utf8_talloc(ctx, &field, utf8_field); string = fn(field, NULL, data_area); if (string) { @@ -1287,7 +1287,7 @@ char *ads_pull_string(ADS_STRUCT *ads, if (!values) return NULL; if (values[0]) { - rc = pull_utf8_talloc(mem_ctx, (void **)&ux_string, + rc = pull_utf8_talloc(mem_ctx, &ux_string, values[0]); if (rc != -1) ret = ux_string; @@ -1321,7 +1321,7 @@ char **ads_pull_strings(ADS_STRUCT *ads, ret = talloc(mem_ctx, sizeof(char *) * (n+1)); for (i=0;i Date: Mon, 5 Aug 2002 02:47:46 +0000 Subject: This fixes a number of ADS problems, particularly with netbiosless setups. - split up the ads structure into logical pieces. This makes it much easier to keep things like the authentication realm and the server realm separate (they can be different). - allow ads callers to specify that no sasl bind should be performed (used by "net ads info" for example) - fix an error with handing ADS_ERROR_SYSTEM() when errno is 0 - completely rewrote the code for finding the LDAP server. Now try DNS methods first, and try all DNS servers returned from the SRV DNS query, sorted by closeness to our interfaces (using the same sort code as we use in replies from WINS servers). This allows us to cope with ADS DCs that are down, and ensures we don't pick one that is on the other side of the country unless absolutely necessary. - recognise dnsRecords as binary when displaying them - cope with the realm not being configured in smb.conf (work it out from the LDAP server) - look at the trustDirection when looking up trusted domains and don't include trusts that trust our domains but we don't trust theirs. - use LDAP to query the alternate (netbios) name for a realm, and make sure that both and long and short forms of the name are accepted by winbindd. Use the short form by default for listing users/groups. - rescan the list of trusted domains every 5 minutes in case new trust relationships are added while winbindd is running - include transient trust relationships (ie. C trusts B, B trusts A, so C trusts A) in winbindd. - don't do a gratuituous node status lookup when finding an ADS DC (we don't need it and it could fail) - remove unused sid_to_distinguished_name function - make sure we find the allternate name of our primary domain when operating with a netbiosless ADS DC (using LDAP to do the lookup) - fixed the rpc trusted domain enumeration to support up to approx 2000 trusted domains (the old limit was 3) - use the IP for the remote_machine (%m) macro when the client doesn't supply us with a name via a netbios session request (eg. port 445) - if the client uses SPNEGO then use the machine name from the SPNEGO auth packet for remote_machine (%m) macro - add new 'net ads workgroup' command to find the netbios workgroup name for a realm (This used to be commit e358d7b24c86a46d8c361b9e32a25d4f71a6dc00) --- source3/libads/ads_struct.c | 119 +++---------- source3/libads/kerberos.c | 12 +- source3/libads/kerberos_verify.c | 2 +- source3/libads/ldap.c | 355 ++++++++++++++++++++++++++++++++------- source3/libads/ldap_user.c | 6 +- source3/libads/sasl.c | 9 +- source3/libads/util.c | 2 +- 7 files changed, 335 insertions(+), 170 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index af0b5d4143..b68c822ce3 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -72,47 +72,6 @@ char *ads_build_dn(const char *realm) } -#ifdef HAVE_LDAP -/* - find the ldap server from DNS -*/ -static char *find_ldap_server(ADS_STRUCT *ads) -{ - char *list = NULL; - struct in_addr ip; - - if (ads->realm && - strcasecmp(ads->workgroup, lp_workgroup()) == 0 && - ldap_domain2hostlist(ads->realm, &list) == LDAP_SUCCESS) { - char *p; - p = strchr(list, ':'); - if (p) *p = 0; - return list; - } - - /* get desperate, find the domain controller IP */ - if (resolve_name(ads->workgroup, &ip, 0x1B)) { - return strdup(inet_ntoa(ip)); - } - - /* or a BDC ... */ - if (resolve_name(ads->workgroup, &ip, 0x1C)) { - return strdup(inet_ntoa(ip)); - } - - return NULL; -} - -#else - -static char *find_ldap_server(ADS_STRUCT *ads) -{ - /* Without LDAP this doesn't make much sense */ - return NULL; -} - -#endif - #ifndef LDAP_PORT #define LDAP_PORT 389 #endif @@ -122,58 +81,24 @@ static char *find_ldap_server(ADS_STRUCT *ads) */ ADS_STRUCT *ads_init(const char *realm, const char *workgroup, - const char *ldap_server, - const char *bind_path, - const char *password) + const char *ldap_server) { ADS_STRUCT *ads; ads = (ADS_STRUCT *)smb_xmalloc(sizeof(*ads)); ZERO_STRUCTP(ads); - if (!workgroup) { - workgroup = lp_workgroup(); + ads->server.realm = realm? strdup(realm) : NULL; + ads->server.workgroup = workgroup ? strdup(workgroup) : NULL; + ads->server.ldap_server = ldap_server? strdup(ldap_server) : NULL; + + /* we need to know if this is a foreign realm to know if we can + use lp_ads_server() */ + if (realm && strcasecmp(lp_realm(), realm) != 0) { + ads->server.foreign = 1; } - - ads->realm = realm? strdup(realm) : NULL; - ads->workgroup = strdup(workgroup); - ads->ldap_server = ldap_server? strdup(ldap_server) : NULL; - ads->bind_path = bind_path? strdup(bind_path) : NULL; - ads->ldap_port = LDAP_PORT; - if (password) ads->password = strdup(password); - - if (!ads->realm) { - ads->realm = strdup(lp_realm()); - if (!ads->realm[0]) { - SAFE_FREE(ads->realm); - } - } - - if (!ads->realm && strchr_m(ads->workgroup, '.')) { - /* the smb.conf has specified the realm in 'workgroup =' */ - ads->realm = strdup(ads->workgroup); - } - - if (!ads->bind_path && ads->realm) { - ads->bind_path = ads_build_dn(ads->realm); - } - if (!ads->ldap_server) { - if (strcasecmp(ads->workgroup, lp_workgroup()) == 0) { - ads->ldap_server = strdup(lp_ads_server()); - } - if (!ads->ldap_server || !ads->ldap_server[0]) { - SAFE_FREE(ads->ldap_server); - ads->ldap_server = find_ldap_server(ads); - } - } - if (!ads->kdc_server) { - /* assume its the same as LDAP */ - ads->kdc_server = ads->ldap_server? strdup(ads->ldap_server) : NULL; - } - - if (ads->ldap_server) { - /* its very useful knowing the IP of the ldap server */ - ads->ldap_ip = *interpret_addr2(ads->ldap_server); + if (workgroup && strcasecmp(lp_workgroup(), workgroup) != 0) { + ads->server.foreign = 1; } return ads; @@ -182,7 +107,7 @@ ADS_STRUCT *ads_init(const char *realm, /* a simpler ads_init() interface using all defaults */ ADS_STRUCT *ads_init_simple(void) { - return ads_init(NULL, NULL, NULL, NULL, NULL); + return ads_init(NULL, NULL, NULL); } /* @@ -194,13 +119,19 @@ void ads_destroy(ADS_STRUCT **ads) #if HAVE_LDAP if ((*ads)->ld) ldap_unbind((*ads)->ld); #endif - SAFE_FREE((*ads)->realm); - SAFE_FREE((*ads)->ldap_server); - SAFE_FREE((*ads)->ldap_server_name); - SAFE_FREE((*ads)->kdc_server); - SAFE_FREE((*ads)->bind_path); - SAFE_FREE((*ads)->password); - SAFE_FREE((*ads)->user_name); + SAFE_FREE((*ads)->server.realm); + SAFE_FREE((*ads)->server.workgroup); + SAFE_FREE((*ads)->server.ldap_server); + + SAFE_FREE((*ads)->auth.realm); + SAFE_FREE((*ads)->auth.password); + SAFE_FREE((*ads)->auth.user_name); + SAFE_FREE((*ads)->auth.kdc_server); + + SAFE_FREE((*ads)->config.realm); + SAFE_FREE((*ads)->config.bind_path); + SAFE_FREE((*ads)->config.ldap_server_name); + ZERO_STRUCTP(*ads); SAFE_FREE(*ads); } diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 1ba5d978e8..9a486237c9 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -110,16 +110,8 @@ int ads_kinit_password(ADS_STRUCT *ads) char *s; int ret; - if (!ads->user_name) { - /* by default use the machine account */ - extern pstring global_myname; - fstring myname; - fstrcpy(myname, global_myname); - strlower(myname); - asprintf(&ads->user_name, "HOST/%s", global_myname); - } - asprintf(&s, "%s@%s", ads->user_name, ads->realm); - ret = kerberos_kinit_password(s, ads->password); + asprintf(&s, "%s@%s", ads->auth.user_name, ads->auth.realm); + ret = kerberos_kinit_password(s, ads->auth.password); if (ret) { DEBUG(0,("kerberos_kinit_password %s failed: %s\n", diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index dac90908c4..22b58f47dd 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -67,7 +67,7 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, return NT_STATUS_LOGON_FAILURE; } - ret = krb5_set_default_realm(context, ads->realm); + ret = krb5_set_default_realm(context, ads->auth.realm); if (ret) { DEBUG(1,("krb5_set_default_realm failed (%s)\n", error_message(ret))); ads_destroy(&ads); diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 1753d7d3ad..a8126faffe 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -37,6 +37,153 @@ * codepoints in UTF-8). This may have to change at some point **/ + +/* + try a connection to a given ldap server, returning True and setting the servers IP + in the ads struct if successful + */ +static BOOL ads_try_connect(ADS_STRUCT *ads, const char *server, unsigned port) +{ + char *srv; + + if (!server || !*server) { + return False; + } + + DEBUG(5,("ads_try_connect: trying ldap server '%s' port %u\n", server, port)); + + /* this copes with inet_ntoa brokenness */ + srv = strdup(server); + + ads->ld = ldap_open(srv, port); + if (!ads->ld) { + free(srv); + return False; + } + ads->ldap_port = port; + ads->ldap_ip = *interpret_addr2(srv); + free(srv); + return True; +} + +/* used by the IP comparison function */ +struct ldap_ip { + struct in_addr ip; + unsigned port; +}; + +/* compare 2 ldap IPs by nearness to our interfaces - used in qsort */ +static int ldap_ip_compare(struct ldap_ip *ip1, struct ldap_ip *ip2) +{ + return ip_compare(&ip1->ip, &ip2->ip); +} + +/* try connecting to a ldap server via DNS */ +static BOOL ads_try_dns(ADS_STRUCT *ads) +{ + char *realm, *ptr; + char *list = NULL; + pstring tok; + struct ldap_ip *ip_list; + int count, i=0; + + realm = ads->server.realm; + if (!realm || !*realm) { + SAFE_FREE(realm); + realm = lp_realm(); + } + if (!realm || !*realm) { + SAFE_FREE(realm); + realm = ads->server.workgroup; + } + if (!realm || !*realm) { + SAFE_FREE(realm); + realm = lp_workgroup(); + } + if (!realm) { + return False; + } + + DEBUG(6,("ads_try_dns: looking for realm '%s'\n", realm)); + if (ldap_domain2hostlist(realm, &list) != LDAP_SUCCESS) { + return False; + } + + DEBUG(6,("ads_try_dns: ldap realm '%s' host list '%s'\n", realm, list)); + + count = count_chars(list, ' ') + 1; + ip_list = malloc(count * sizeof(struct ldap_ip)); + if (!ip_list) { + return False; + } + + ptr = list; + while (next_token(&ptr, tok, " ", sizeof(tok))) { + unsigned port = LDAP_PORT; + char *p = strchr(tok, ':'); + if (p) { + *p = 0; + port = atoi(p+1); + } + ip_list[i].ip = *interpret_addr2(tok); + ip_list[i].port = port; + if (!is_zero_ip(ip_list[i].ip)) { + i++; + } + } + free(list); + + count = i; + + /* we sort the list of addresses by closeness to our interfaces. This + tries to prevent us using a DC on the other side of the country */ + if (count > 1) { + qsort(ip_list, count, sizeof(struct ldap_ip), + QSORT_CAST ldap_ip_compare); + } + + for (i=0;iserver.workgroup; + + if (!workgroup) { + workgroup = lp_workgroup(); + } + + DEBUG(6,("ads_try_netbios: looking for workgroup '%s'\n", workgroup)); + + if (!get_dc_list(True, workgroup, &ip_list, &count) && + !get_dc_list(False, workgroup, &ip_list, &count)) { + return False; + } + + for (i=0;ilast_attempt = time(NULL); - ads->ld = NULL; - if (ads->ldap_server) { - ads->ld = ldap_open(ads->ldap_server, ads->ldap_port); + /* try with a user specified server */ + if (ads->server.ldap_server && + ads_try_connect(ads, ads->server.ldap_server, LDAP_PORT)) { + goto got_connection; } - /* if that failed then try each of the BDC's in turn */ - if (!ads->ld) { - struct in_addr *ip_list; - int count; - - if (get_dc_list(False, ads->workgroup, &ip_list, &count)) { - int i; - for (i=0;ild = ldap_open(inet_ntoa(ip_list[i]), - ads->ldap_port); - if (ads->ld) break; - } - if (ads->ld) { - SAFE_FREE(ads->ldap_server); - ads->ldap_server = strdup(inet_ntoa(ip_list[i])); - } - free(ip_list); - } + /* try with a smb.conf ads server setting if we are connecting + to the primary workgroup or realm */ + if (!ads->server.foreign && + ads_try_connect(ads, lp_ads_server(), LDAP_PORT)) { + goto got_connection; } - if (!ads->ld) { - return ADS_ERROR_SYSTEM(errno); + /* try via DNS */ + if (ads_try_dns(ads)) { + goto got_connection; + } + + /* try via netbios lookups */ + if (!lp_disable_netbios() && ads_try_netbios(ads)) { + goto got_connection; } - DEBUG(3,("Connected to LDAP server %s\n", ads->ldap_server)); + return ADS_ERROR_SYSTEM(errno?errno:ENOENT); + +got_connection: + DEBUG(3,("Connected to LDAP server %s\n", inet_ntoa(ads->ldap_ip))); status = ads_server_info(ads); if (!ADS_ERR_OK(status)) { @@ -90,22 +234,43 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); + if (!ads->auth.user_name) { + /* by default use the machine account */ + extern pstring global_myname; + fstring myname; + fstrcpy(myname, global_myname); + strlower(myname); + asprintf(&ads->auth.user_name, "HOST/%s", myname); + } + + if (!ads->auth.realm) { + ads->auth.realm = strdup(ads->config.realm); + } + + if (!ads->auth.kdc_server) { + ads->auth.kdc_server = strdup(inet_ntoa(ads->ldap_ip)); + } + #if KRB5_DNS_HACK /* this is a really nasty hack to avoid ADS DNS problems. It needs a patch to MIT kerberos to work (tridge) */ { char *env; - asprintf(&env, "KRB5_KDC_ADDRESS_%s", ads->server_realm); - setenv(env, inet_ntoa(*interpret_addr2(ads->ldap_server)), 1); + asprintf(&env, "KRB5_KDC_ADDRESS_%s", ads->config.realm); + setenv(env, ads->auth.kdc_server, 1); free(env); } #endif - if (ads->password) { + if (ads->auth.password) { if ((code = ads_kinit_password(ads))) return ADS_ERROR_KRB5(code); } + if (ads->auth.no_bind) { + return ADS_SUCCESS; + } + return ads_sasl_bind(ads); } @@ -494,7 +659,7 @@ ADS_STATUS ads_search(ADS_STRUCT *ads, void **res, const char *exp, const char **attrs) { - return ads_do_search(ads, ads->bind_path, LDAP_SCOPE_SUBTREE, + return ads_do_search(ads, ads->config.bind_path, LDAP_SCOPE_SUBTREE, exp, attrs, res); } @@ -805,11 +970,11 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, if (!(host_spn = talloc_asprintf(ctx, "HOST/%s", hostname))) goto done; - if (!(host_upn = talloc_asprintf(ctx, "%s@%s", host_spn, ads->realm))) + if (!(host_upn = talloc_asprintf(ctx, "%s@%s", host_spn, ads->config.realm))) goto done; ou_str = ads_ou_string(org_unit); new_dn = talloc_asprintf(ctx, "cn=%s,%s,%s", hostname, ou_str, - ads->bind_path); + ads->config.bind_path); free(ou_str); if (!new_dn) goto done; @@ -925,6 +1090,7 @@ static BOOL ads_dump_field(char *field, void **values, void *data_area) } handlers[] = { {"objectGUID", False, dump_binary}, {"nTSecurityDescriptor", False, dump_sd}, + {"dnsRecord", False, dump_binary}, {"objectSid", False, dump_sid}, {NULL, True, NULL} }; @@ -1061,7 +1227,7 @@ ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *hostname, const char *org status = ads_leave_realm(ads, host); if (!ADS_ERR_OK(status)) { DEBUG(0, ("Failed to delete host '%s' from the '%s' realm.\n", - host, ads->realm)); + host, ads->config.realm)); return status; } } @@ -1224,20 +1390,15 @@ ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads, char *host = strdup(hostname); char *principal; - if (!ads->kdc_server) { - DEBUG(0, ("Unable to find KDC server\n")); - return ADS_ERROR(LDAP_SERVER_DOWN); - } - strlower(host); /* we need to use the '$' form of the name here, as otherwise the server might end up setting the password for a user instead */ - asprintf(&principal, "%s$@%s", host, ads->realm); + asprintf(&principal, "%s$@%s", host, ads->auth.realm); - status = krb5_set_password(ads->kdc_server, principal, password); + status = krb5_set_password(ads->auth.kdc_server, principal, password); free(host); free(principal); @@ -1472,33 +1633,27 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads) return ADS_ERROR(LDAP_DECODING_ERROR); } - SAFE_FREE(ads->ldap_server_name); + SAFE_FREE(ads->config.ldap_server_name); - ads->ldap_server_name = strdup(p+1); - p = strchr(ads->ldap_server_name, '$'); + ads->config.ldap_server_name = strdup(p+1); + p = strchr(ads->config.ldap_server_name, '$'); if (!p || p[1] != '@') { ldap_value_free(values); ldap_msgfree(res); - SAFE_FREE(ads->ldap_server_name); + SAFE_FREE(ads->config.ldap_server_name); return ADS_ERROR(LDAP_DECODING_ERROR); } *p = 0; - SAFE_FREE(ads->server_realm); - SAFE_FREE(ads->bind_path); + SAFE_FREE(ads->config.realm); + SAFE_FREE(ads->config.bind_path); - ads->server_realm = strdup(p+2); - ads->bind_path = ads_build_dn(ads->server_realm); - - /* in case the realm isn't configured in smb.conf */ - if (!ads->realm || !ads->realm[0]) { - SAFE_FREE(ads->realm); - ads->realm = strdup(ads->server_realm); - } + ads->config.realm = strdup(p+2); + ads->config.bind_path = ads_build_dn(ads->config.realm); DEBUG(3,("got ldap server name %s@%s\n", - ads->ldap_server_name, ads->realm)); + ads->config.ldap_server_name, ads->config.realm)); return ADS_SUCCESS; } @@ -1514,9 +1669,13 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads) * @return the count of SIDs pulled **/ ADS_STATUS ads_trusted_domains(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, - int *num_trusts, char ***names, DOM_SID **sids) + int *num_trusts, + char ***names, + char ***alt_names, + DOM_SID **sids) { - const char *attrs[] = {"flatName", "securityIdentifier", NULL}; + const char *attrs[] = {"name", "flatname", "securityIdentifier", + "trustDirection", NULL}; ADS_STATUS status; void *res, *msg; int count, i; @@ -1533,11 +1692,31 @@ ADS_STATUS ads_trusted_domains(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, } (*names) = talloc(mem_ctx, sizeof(char *) * count); + (*alt_names) = talloc(mem_ctx, sizeof(char *) * count); (*sids) = talloc(mem_ctx, sizeof(DOM_SID) * count); if (! *names || ! *sids) return ADS_ERROR(LDAP_NO_MEMORY); for (i=0, msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) { - (*names)[i] = ads_pull_string(ads, mem_ctx, msg, "flatName"); + uint32 direction; + + /* direction is a 2 bit bitfield, 1 means they trust us + but we don't trust them, so we should not list them + as users from that domain can't login */ + if (ads_pull_uint32(ads, msg, "trustDirection", &direction) && + direction == 1) { + continue; + } + + (*names)[i] = ads_pull_string(ads, mem_ctx, msg, "name"); + (*alt_names)[i] = ads_pull_string(ads, mem_ctx, msg, "flatname"); + + if ((*alt_names)[i] && (*alt_names)[i][0]) { + /* we prefer the flatname as the primary name + for consistency with RPC */ + char *name = (*alt_names)[i]; + (*alt_names)[i] = (*names)[i]; + (*names)[i] = name; + } if (ads_pull_sid(ads, msg, "securityIdentifier", &(*sids)[i])) { i++; } @@ -1562,7 +1741,7 @@ ADS_STATUS ads_domain_sid(ADS_STRUCT *ads, DOM_SID *sid) void *res; ADS_STATUS rc; - rc = ads_do_search(ads, ads->bind_path, LDAP_SCOPE_BASE, "(objectclass=*)", + rc = ads_do_search(ads, ads->config.bind_path, LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); if (!ADS_ERR_OK(rc)) return rc; if (!ads_pull_sid(ads, res, "objectSid", sid)) { @@ -1573,4 +1752,66 @@ ADS_STATUS ads_domain_sid(ADS_STRUCT *ads, DOM_SID *sid) return ADS_SUCCESS; } +/* this is rather complex - we need to find the allternate (netbios) name + for the domain, but there isn't a simple query to do this. Instead + we look for the principle names on the DCs account and find one that has + the right form, then extract the netbios name of the domain from that +*/ +ADS_STATUS ads_workgroup_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char **workgroup) +{ + char *exp; + ADS_STATUS rc; + char **principles; + char *prefix; + int prefix_length; + int i; + void *res; + const char *attrs[] = {"servicePrincipalName", NULL}; + + (*workgroup) = NULL; + + asprintf(&exp, "(&(objectclass=computer)(dnshostname=%s.%s))", + ads->config.ldap_server_name, ads->config.realm); + rc = ads_search(ads, &res, exp, attrs); + free(exp); + + if (!ADS_ERR_OK(rc)) { + return rc; + } + + principles = ads_pull_strings(ads, mem_ctx, res, "servicePrincipalName"); + + ads_msgfree(ads, res); + + if (!principles) { + return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); + } + + asprintf(&prefix, "HOST/%s.%s/", + ads->config.ldap_server_name, + ads->config.realm); + + prefix_length = strlen(prefix); + + for (i=0;principles[i]; i++) { + if (strncasecmp(principles[i], prefix, prefix_length) == 0 && + strcasecmp(ads->config.realm, principles[i]+prefix_length) != 0 && + !strchr(principles[i]+prefix_length, '.')) { + /* found an alternate (short) name for the domain. */ + DEBUG(3,("Found alternate name '%s' for realm '%s'\n", + principles[i]+prefix_length, + ads->config.realm)); + (*workgroup) = talloc_strdup(mem_ctx, principles[i]+prefix_length); + break; + } + } + free(prefix); + + if (!*workgroup) { + return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); + } + + return ADS_SUCCESS; +} + #endif diff --git a/source3/libads/ldap_user.c b/source3/libads/ldap_user.c index b6e3d189c5..b6fef24b5c 100644 --- a/source3/libads/ldap_user.c +++ b/source3/libads/ldap_user.c @@ -55,10 +55,10 @@ ADS_STATUS ads_add_user_acct(ADS_STRUCT *ads, const char *user, status = ADS_ERROR(LDAP_NO_MEMORY); - if (!(upn = talloc_asprintf(ctx, "%s@%s", user, ads->realm))) + if (!(upn = talloc_asprintf(ctx, "%s@%s", user, ads->config.realm))) goto done; if (!(new_dn = talloc_asprintf(ctx, "cn=%s,cn=Users,%s", name, - ads->bind_path))) + ads->config.bind_path))) goto done; if (!(controlstr = talloc_asprintf(ctx, "%u", UF_NORMAL_ACCOUNT))) goto done; @@ -94,7 +94,7 @@ ADS_STATUS ads_add_group_acct(ADS_STRUCT *ads, const char *group, status = ADS_ERROR(LDAP_NO_MEMORY); if (!(new_dn = talloc_asprintf(ctx, "cn=%s,cn=Users,%s", group, - ads->bind_path))) + ads->config.bind_path))) goto done; if (!(mods = ads_init_mods(ctx))) goto done; diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 1b55453cac..81dedb0a81 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -77,7 +77,7 @@ ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) /* we need to fetch a service ticket as the ldap user in the servers realm, regardless of our realm */ - asprintf(&sname, "ldap/%s@%s", ads->ldap_server_name, ads->server_realm); + asprintf(&sname, "ldap/%s@%s", ads->config.ldap_server_name, ads->config.realm); krb5_init_context(&ctx); krb5_set_default_tgs_ktypes(ctx, enc_types); krb5_parse_name(ctx, sname, &principal); @@ -163,7 +163,7 @@ ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) gss_release_buffer(&minor_status, &output_token); - output_token.value = malloc(strlen(ads->bind_path) + 8); + output_token.value = malloc(strlen(ads->config.bind_path) + 8); p = output_token.value; *p++ = 1; /* no sign or seal */ @@ -171,9 +171,10 @@ ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) *p++ = max_msg_size>>16; *p++ = max_msg_size>>8; *p++ = max_msg_size; - snprintf(p, strlen(ads->bind_path)+4, "dn:%s", ads->bind_path); + snprintf(p, strlen(ads->config.bind_path)+4, "dn:%s", ads->config.bind_path); + p += strlen(ads->config.bind_path); - output_token.length = strlen(ads->bind_path) + 8; + output_token.length = strlen(ads->config.bind_path) + 8; gss_rc = gss_wrap(&minor_status, context_handle,0,GSS_C_QOP_DEFAULT, &output_token, &conf_state, diff --git a/source3/libads/util.c b/source3/libads/util.c index d48eb10b71..b10b130a31 100644 --- a/source3/libads/util.c +++ b/source3/libads/util.c @@ -39,7 +39,7 @@ ADS_STATUS ads_change_trust_account_password(ADS_STRUCT *ads, char *host_princip new_password = strdup(tmp_password); asprintf(&service_principal, "HOST/%s", host_principal); - ret = kerberos_set_password(ads->kdc_server, host_principal, password, + ret = kerberos_set_password(ads->auth.kdc_server, host_principal, password, service_principal, new_password); if (!secrets_store_machine_password(new_password)) { -- cgit From 74c8441e9d21f317b74032b5bdd17c8d2f78c015 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 6 Aug 2002 03:26:58 +0000 Subject: fixed a memory corruption bug in ads_try_dns() (This used to be commit 2ee0abb50f25e5a4529d8c9409c979a7a00e5984) --- source3/libads/ldap.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index a8126faffe..c8d940f331 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -89,27 +89,27 @@ static BOOL ads_try_dns(ADS_STRUCT *ads) realm = ads->server.realm; if (!realm || !*realm) { - SAFE_FREE(realm); realm = lp_realm(); } if (!realm || !*realm) { - SAFE_FREE(realm); realm = ads->server.workgroup; } if (!realm || !*realm) { - SAFE_FREE(realm); realm = lp_workgroup(); } if (!realm) { return False; } + realm = smb_xstrdup(realm); DEBUG(6,("ads_try_dns: looking for realm '%s'\n", realm)); if (ldap_domain2hostlist(realm, &list) != LDAP_SUCCESS) { + SAFE_FREE(realm); return False; } DEBUG(6,("ads_try_dns: ldap realm '%s' host list '%s'\n", realm, list)); + SAFE_FREE(realm); count = count_chars(list, ' ') + 1; ip_list = malloc(count * sizeof(struct ldap_ip)); -- cgit From 4361b5cea56972b534ba36d89b521f9ad240d3d7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 6 Aug 2002 05:11:57 +0000 Subject: when using netbios lookup methods make sure we try any BDCs even if we get a response from WINS for a PDC, if the PDC isn't responding. (This used to be commit 57916316ffc70b0b6659f3ad9d14aad41fad4c71) --- source3/libads/ldap.c | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index c8d940f331..2672489482 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -167,20 +167,32 @@ static BOOL ads_try_netbios(ADS_STRUCT *ads) DEBUG(6,("ads_try_netbios: looking for workgroup '%s'\n", workgroup)); - if (!get_dc_list(True, workgroup, &ip_list, &count) && - !get_dc_list(False, workgroup, &ip_list, &count)) { - return False; + /* try the PDC first */ + if (get_dc_list(True, workgroup, &ip_list, &count)) { + for (i=0;i Date: Sat, 17 Aug 2002 17:00:51 +0000 Subject: sync 3.0 branch with head (This used to be commit 3928578b52cfc949be5e0ef444fce1558d75f290) --- source3/libads/ads_struct.c | 107 +++-------- source3/libads/kerberos.c | 12 +- source3/libads/kerberos_verify.c | 2 +- source3/libads/ldap.c | 389 ++++++++++++++++++++++++++++++++------- source3/libads/ldap_user.c | 6 +- source3/libads/sasl.c | 9 +- source3/libads/util.c | 2 +- 7 files changed, 358 insertions(+), 169 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index 638dc0b22e..b68c822ce3 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -72,47 +72,6 @@ char *ads_build_dn(const char *realm) } -#ifdef HAVE_LDAP -/* - find the ldap server from DNS -*/ -static char *find_ldap_server(ADS_STRUCT *ads) -{ - char *list = NULL; - struct in_addr ip; - - if (ads->realm && - strcasecmp(ads->workgroup, lp_workgroup()) == 0 && - ldap_domain2hostlist(ads->realm, &list) == LDAP_SUCCESS) { - char *p; - p = strchr(list, ':'); - if (p) *p = 0; - return list; - } - - /* get desperate, find the domain controller IP */ - if (resolve_name(ads->workgroup, &ip, 0x1B)) { - return strdup(inet_ntoa(ip)); - } - - /* or a BDC ... */ - if (resolve_name(ads->workgroup, &ip, 0x1C)) { - return strdup(inet_ntoa(ip)); - } - - return NULL; -} - -#else - -static char *find_ldap_server(ADS_STRUCT *ads) -{ - /* Without LDAP this doesn't make much sense */ - return NULL; -} - -#endif - #ifndef LDAP_PORT #define LDAP_PORT 389 #endif @@ -122,46 +81,24 @@ static char *find_ldap_server(ADS_STRUCT *ads) */ ADS_STRUCT *ads_init(const char *realm, const char *workgroup, - const char *ldap_server, - const char *bind_path, - const char *password) + const char *ldap_server) { ADS_STRUCT *ads; ads = (ADS_STRUCT *)smb_xmalloc(sizeof(*ads)); ZERO_STRUCTP(ads); - if (!workgroup) { - workgroup = lp_workgroup(); + ads->server.realm = realm? strdup(realm) : NULL; + ads->server.workgroup = workgroup ? strdup(workgroup) : NULL; + ads->server.ldap_server = ldap_server? strdup(ldap_server) : NULL; + + /* we need to know if this is a foreign realm to know if we can + use lp_ads_server() */ + if (realm && strcasecmp(lp_realm(), realm) != 0) { + ads->server.foreign = 1; } - - ads->realm = realm? strdup(realm) : NULL; - ads->workgroup = strdup(workgroup); - ads->ldap_server = ldap_server? strdup(ldap_server) : NULL; - ads->bind_path = bind_path? strdup(bind_path) : NULL; - ads->ldap_port = LDAP_PORT; - if (password) ads->password = strdup(password); - - if (!ads->realm) { - ads->realm = strdup(lp_realm()); - if (!ads->realm[0]) { - SAFE_FREE(ads->realm); - } - } - if (!ads->bind_path && ads->realm) { - ads->bind_path = ads_build_dn(ads->realm); - } - if (!ads->ldap_server) { - if (strcasecmp(ads->workgroup, lp_workgroup()) == 0) { - ads->ldap_server = strdup(lp_ads_server()); - } - if (!ads->ldap_server || !ads->ldap_server[0]) { - ads->ldap_server = find_ldap_server(ads); - } - } - if (!ads->kdc_server) { - /* assume its the same as LDAP */ - ads->kdc_server = ads->ldap_server? strdup(ads->ldap_server) : NULL; + if (workgroup && strcasecmp(lp_workgroup(), workgroup) != 0) { + ads->server.foreign = 1; } return ads; @@ -170,7 +107,7 @@ ADS_STRUCT *ads_init(const char *realm, /* a simpler ads_init() interface using all defaults */ ADS_STRUCT *ads_init_simple(void) { - return ads_init(NULL, NULL, NULL, NULL, NULL); + return ads_init(NULL, NULL, NULL); } /* @@ -182,13 +119,19 @@ void ads_destroy(ADS_STRUCT **ads) #if HAVE_LDAP if ((*ads)->ld) ldap_unbind((*ads)->ld); #endif - SAFE_FREE((*ads)->realm); - SAFE_FREE((*ads)->ldap_server); - SAFE_FREE((*ads)->ldap_server_name); - SAFE_FREE((*ads)->kdc_server); - SAFE_FREE((*ads)->bind_path); - SAFE_FREE((*ads)->password); - SAFE_FREE((*ads)->user_name); + SAFE_FREE((*ads)->server.realm); + SAFE_FREE((*ads)->server.workgroup); + SAFE_FREE((*ads)->server.ldap_server); + + SAFE_FREE((*ads)->auth.realm); + SAFE_FREE((*ads)->auth.password); + SAFE_FREE((*ads)->auth.user_name); + SAFE_FREE((*ads)->auth.kdc_server); + + SAFE_FREE((*ads)->config.realm); + SAFE_FREE((*ads)->config.bind_path); + SAFE_FREE((*ads)->config.ldap_server_name); + ZERO_STRUCTP(*ads); SAFE_FREE(*ads); } diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 1ba5d978e8..9a486237c9 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -110,16 +110,8 @@ int ads_kinit_password(ADS_STRUCT *ads) char *s; int ret; - if (!ads->user_name) { - /* by default use the machine account */ - extern pstring global_myname; - fstring myname; - fstrcpy(myname, global_myname); - strlower(myname); - asprintf(&ads->user_name, "HOST/%s", global_myname); - } - asprintf(&s, "%s@%s", ads->user_name, ads->realm); - ret = kerberos_kinit_password(s, ads->password); + asprintf(&s, "%s@%s", ads->auth.user_name, ads->auth.realm); + ret = kerberos_kinit_password(s, ads->auth.password); if (ret) { DEBUG(0,("kerberos_kinit_password %s failed: %s\n", diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index dac90908c4..22b58f47dd 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -67,7 +67,7 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, return NT_STATUS_LOGON_FAILURE; } - ret = krb5_set_default_realm(context, ads->realm); + ret = krb5_set_default_realm(context, ads->auth.realm); if (ret) { DEBUG(1,("krb5_set_default_realm failed (%s)\n", error_message(ret))); ads_destroy(&ads); diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 9d15c4e33c..2672489482 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -37,6 +37,165 @@ * codepoints in UTF-8). This may have to change at some point **/ + +/* + try a connection to a given ldap server, returning True and setting the servers IP + in the ads struct if successful + */ +static BOOL ads_try_connect(ADS_STRUCT *ads, const char *server, unsigned port) +{ + char *srv; + + if (!server || !*server) { + return False; + } + + DEBUG(5,("ads_try_connect: trying ldap server '%s' port %u\n", server, port)); + + /* this copes with inet_ntoa brokenness */ + srv = strdup(server); + + ads->ld = ldap_open(srv, port); + if (!ads->ld) { + free(srv); + return False; + } + ads->ldap_port = port; + ads->ldap_ip = *interpret_addr2(srv); + free(srv); + return True; +} + +/* used by the IP comparison function */ +struct ldap_ip { + struct in_addr ip; + unsigned port; +}; + +/* compare 2 ldap IPs by nearness to our interfaces - used in qsort */ +static int ldap_ip_compare(struct ldap_ip *ip1, struct ldap_ip *ip2) +{ + return ip_compare(&ip1->ip, &ip2->ip); +} + +/* try connecting to a ldap server via DNS */ +static BOOL ads_try_dns(ADS_STRUCT *ads) +{ + char *realm, *ptr; + char *list = NULL; + pstring tok; + struct ldap_ip *ip_list; + int count, i=0; + + realm = ads->server.realm; + if (!realm || !*realm) { + realm = lp_realm(); + } + if (!realm || !*realm) { + realm = ads->server.workgroup; + } + if (!realm || !*realm) { + realm = lp_workgroup(); + } + if (!realm) { + return False; + } + realm = smb_xstrdup(realm); + + DEBUG(6,("ads_try_dns: looking for realm '%s'\n", realm)); + if (ldap_domain2hostlist(realm, &list) != LDAP_SUCCESS) { + SAFE_FREE(realm); + return False; + } + + DEBUG(6,("ads_try_dns: ldap realm '%s' host list '%s'\n", realm, list)); + SAFE_FREE(realm); + + count = count_chars(list, ' ') + 1; + ip_list = malloc(count * sizeof(struct ldap_ip)); + if (!ip_list) { + return False; + } + + ptr = list; + while (next_token(&ptr, tok, " ", sizeof(tok))) { + unsigned port = LDAP_PORT; + char *p = strchr(tok, ':'); + if (p) { + *p = 0; + port = atoi(p+1); + } + ip_list[i].ip = *interpret_addr2(tok); + ip_list[i].port = port; + if (!is_zero_ip(ip_list[i].ip)) { + i++; + } + } + free(list); + + count = i; + + /* we sort the list of addresses by closeness to our interfaces. This + tries to prevent us using a DC on the other side of the country */ + if (count > 1) { + qsort(ip_list, count, sizeof(struct ldap_ip), + QSORT_CAST ldap_ip_compare); + } + + for (i=0;iserver.workgroup; + + if (!workgroup) { + workgroup = lp_workgroup(); + } + + DEBUG(6,("ads_try_netbios: looking for workgroup '%s'\n", workgroup)); + + /* try the PDC first */ + if (get_dc_list(True, workgroup, &ip_list, &count)) { + for (i=0;ilast_attempt = time(NULL); - ads->ld = NULL; - if (ads->ldap_server) { - ads->ld = ldap_open(ads->ldap_server, ads->ldap_port); + /* try with a user specified server */ + if (ads->server.ldap_server && + ads_try_connect(ads, ads->server.ldap_server, LDAP_PORT)) { + goto got_connection; } - /* if that failed then try each of the BDC's in turn */ - if (!ads->ld) { - struct in_addr *ip_list; - int count; - - if (get_dc_list(False, ads->workgroup, &ip_list, &count)) { - int i; - for (i=0;ild = ldap_open(inet_ntoa(ip_list[i]), - ads->ldap_port); - if (ads->ld) break; - } - if (ads->ld) { - SAFE_FREE(ads->ldap_server); - ads->ldap_server = strdup(inet_ntoa(ip_list[i])); - } - free(ip_list); - } + /* try with a smb.conf ads server setting if we are connecting + to the primary workgroup or realm */ + if (!ads->server.foreign && + ads_try_connect(ads, lp_ads_server(), LDAP_PORT)) { + goto got_connection; } - if (!ads->ld) { - return ADS_ERROR_SYSTEM(errno); + /* try via DNS */ + if (ads_try_dns(ads)) { + goto got_connection; + } + + /* try via netbios lookups */ + if (!lp_disable_netbios() && ads_try_netbios(ads)) { + goto got_connection; } - DEBUG(3,("Connected to LDAP server %s\n", ads->ldap_server)); + return ADS_ERROR_SYSTEM(errno?errno:ENOENT); + +got_connection: + DEBUG(3,("Connected to LDAP server %s\n", inet_ntoa(ads->ldap_ip))); status = ads_server_info(ads); if (!ADS_ERR_OK(status)) { @@ -90,22 +246,43 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); + if (!ads->auth.user_name) { + /* by default use the machine account */ + extern pstring global_myname; + fstring myname; + fstrcpy(myname, global_myname); + strlower(myname); + asprintf(&ads->auth.user_name, "HOST/%s", myname); + } + + if (!ads->auth.realm) { + ads->auth.realm = strdup(ads->config.realm); + } + + if (!ads->auth.kdc_server) { + ads->auth.kdc_server = strdup(inet_ntoa(ads->ldap_ip)); + } + #if KRB5_DNS_HACK /* this is a really nasty hack to avoid ADS DNS problems. It needs a patch to MIT kerberos to work (tridge) */ { char *env; - asprintf(&env, "KRB5_KDC_ADDRESS_%s", ads->server_realm); - setenv(env, inet_ntoa(*interpret_addr2(ads->ldap_server)), 1); + asprintf(&env, "KRB5_KDC_ADDRESS_%s", ads->config.realm); + setenv(env, ads->auth.kdc_server, 1); free(env); } #endif - if (ads->password) { + if (ads->auth.password) { if ((code = ads_kinit_password(ads))) return ADS_ERROR_KRB5(code); } + if (ads->auth.no_bind) { + return ADS_SUCCESS; + } + return ads_sasl_bind(ads); } @@ -161,7 +338,7 @@ static char **ads_push_strvals(TALLOC_CTX *ctx, const char **in_vals) if (!values) return NULL; for (i=0; in_vals[i]; i++) { - push_utf8_talloc(ctx, (void **) &values[i], in_vals[i]); + push_utf8_talloc(ctx, &values[i], in_vals[i]); } return values; } @@ -180,7 +357,7 @@ static char **ads_pull_strvals(TALLOC_CTX *ctx, const char **in_vals) if (!values) return NULL; for (i=0; in_vals[i]; i++) { - pull_utf8_talloc(ctx, (void **) &values[i], in_vals[i]); + pull_utf8_talloc(ctx, &values[i], in_vals[i]); } return values; } @@ -219,8 +396,8 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, /* 0 means the conversion worked but the result was empty so we only fail if it's negative. In any case, it always at least nulls out the dest */ - if ((push_utf8_talloc(ctx, (void **) &utf8_exp, exp) < 0) || - (push_utf8_talloc(ctx, (void **) &utf8_path, bind_path) < 0)) { + if ((push_utf8_talloc(ctx, &utf8_exp, exp) < 0) || + (push_utf8_talloc(ctx, &utf8_path, bind_path) < 0)) { rc = LDAP_NO_MEMORY; goto done; } @@ -230,7 +407,7 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, else { /* This would be the utf8-encoded version...*/ /* if (!(search_attrs = ads_push_strvals(ctx, attrs))) */ - if (!(str_list_copy(&search_attrs, (char **) attrs))) + if (!(str_list_copy(&search_attrs, attrs))) { rc = LDAP_NO_MEMORY; goto done; @@ -442,8 +619,8 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, /* 0 means the conversion worked but the result was empty so we only fail if it's negative. In any case, it always at least nulls out the dest */ - if ((push_utf8_talloc(ctx, (void **) &utf8_exp, exp) < 0) || - (push_utf8_talloc(ctx, (void **) &utf8_path, bind_path) < 0)) { + if ((push_utf8_talloc(ctx, &utf8_exp, exp) < 0) || + (push_utf8_talloc(ctx, &utf8_path, bind_path) < 0)) { rc = LDAP_NO_MEMORY; goto done; } @@ -453,7 +630,7 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, else { /* This would be the utf8-encoded version...*/ /* if (!(search_attrs = ads_push_strvals(ctx, attrs))) */ - if (!(str_list_copy(&search_attrs, (char **) attrs))) + if (!(str_list_copy(&search_attrs, attrs))) { rc = LDAP_NO_MEMORY; goto done; @@ -494,7 +671,7 @@ ADS_STATUS ads_search(ADS_STRUCT *ads, void **res, const char *exp, const char **attrs) { - return ads_do_search(ads, ads->bind_path, LDAP_SCOPE_SUBTREE, + return ads_do_search(ads, ads->config.bind_path, LDAP_SCOPE_SUBTREE, exp, attrs, res); } @@ -805,11 +982,11 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, if (!(host_spn = talloc_asprintf(ctx, "HOST/%s", hostname))) goto done; - if (!(host_upn = talloc_asprintf(ctx, "%s@%s", host_spn, ads->realm))) + if (!(host_upn = talloc_asprintf(ctx, "%s@%s", host_spn, ads->config.realm))) goto done; ou_str = ads_ou_string(org_unit); new_dn = talloc_asprintf(ctx, "cn=%s,%s,%s", hostname, ou_str, - ads->bind_path); + ads->config.bind_path); free(ou_str); if (!new_dn) goto done; @@ -925,6 +1102,7 @@ static BOOL ads_dump_field(char *field, void **values, void *data_area) } handlers[] = { {"objectGUID", False, dump_binary}, {"nTSecurityDescriptor", False, dump_sd}, + {"dnsRecord", False, dump_binary}, {"objectSid", False, dump_sid}, {NULL, True, NULL} }; @@ -999,7 +1177,7 @@ void ads_process_results(ADS_STRUCT *ads, void *res, char *field; BOOL string; - pull_utf8_talloc(ctx, (void **) &field, utf8_field); + pull_utf8_talloc(ctx, &field, utf8_field); string = fn(field, NULL, data_area); if (string) { @@ -1061,7 +1239,7 @@ ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *hostname, const char *org status = ads_leave_realm(ads, host); if (!ADS_ERR_OK(status)) { DEBUG(0, ("Failed to delete host '%s' from the '%s' realm.\n", - host, ads->realm)); + host, ads->config.realm)); return status; } } @@ -1224,20 +1402,15 @@ ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads, char *host = strdup(hostname); char *principal; - if (!ads->kdc_server) { - DEBUG(0, ("Unable to find KDC server\n")); - return ADS_ERROR(LDAP_SERVER_DOWN); - } - strlower(host); /* we need to use the '$' form of the name here, as otherwise the server might end up setting the password for a user instead */ - asprintf(&principal, "%s$@%s", host, ads->realm); + asprintf(&principal, "%s$@%s", host, ads->auth.realm); - status = krb5_set_password(ads->kdc_server, principal, password); + status = krb5_set_password(ads->auth.kdc_server, principal, password); free(host); free(principal); @@ -1287,7 +1460,7 @@ char *ads_pull_string(ADS_STRUCT *ads, if (!values) return NULL; if (values[0]) { - rc = pull_utf8_talloc(mem_ctx, (void **)&ux_string, + rc = pull_utf8_talloc(mem_ctx, &ux_string, values[0]); if (rc != -1) ret = ux_string; @@ -1321,7 +1494,7 @@ char **ads_pull_strings(ADS_STRUCT *ads, ret = talloc(mem_ctx, sizeof(char *) * (n+1)); for (i=0;ildap_server_name); + SAFE_FREE(ads->config.ldap_server_name); - ads->ldap_server_name = strdup(p+1); - p = strchr(ads->ldap_server_name, '$'); + ads->config.ldap_server_name = strdup(p+1); + p = strchr(ads->config.ldap_server_name, '$'); if (!p || p[1] != '@') { ldap_value_free(values); ldap_msgfree(res); - SAFE_FREE(ads->ldap_server_name); + SAFE_FREE(ads->config.ldap_server_name); return ADS_ERROR(LDAP_DECODING_ERROR); } *p = 0; - SAFE_FREE(ads->server_realm); - SAFE_FREE(ads->bind_path); + SAFE_FREE(ads->config.realm); + SAFE_FREE(ads->config.bind_path); - ads->server_realm = strdup(p+2); - ads->bind_path = ads_build_dn(ads->server_realm); - - /* in case the realm isn't configured in smb.conf */ - if (!ads->realm || !ads->realm[0]) { - SAFE_FREE(ads->realm); - ads->realm = strdup(ads->server_realm); - } + ads->config.realm = strdup(p+2); + ads->config.bind_path = ads_build_dn(ads->config.realm); DEBUG(3,("got ldap server name %s@%s\n", - ads->ldap_server_name, ads->realm)); + ads->config.ldap_server_name, ads->config.realm)); return ADS_SUCCESS; } @@ -1514,9 +1681,13 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads) * @return the count of SIDs pulled **/ ADS_STATUS ads_trusted_domains(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, - int *num_trusts, char ***names, DOM_SID **sids) + int *num_trusts, + char ***names, + char ***alt_names, + DOM_SID **sids) { - const char *attrs[] = {"flatName", "securityIdentifier", NULL}; + const char *attrs[] = {"name", "flatname", "securityIdentifier", + "trustDirection", NULL}; ADS_STATUS status; void *res, *msg; int count, i; @@ -1533,11 +1704,31 @@ ADS_STATUS ads_trusted_domains(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, } (*names) = talloc(mem_ctx, sizeof(char *) * count); + (*alt_names) = talloc(mem_ctx, sizeof(char *) * count); (*sids) = talloc(mem_ctx, sizeof(DOM_SID) * count); if (! *names || ! *sids) return ADS_ERROR(LDAP_NO_MEMORY); for (i=0, msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) { - (*names)[i] = ads_pull_string(ads, mem_ctx, msg, "flatName"); + uint32 direction; + + /* direction is a 2 bit bitfield, 1 means they trust us + but we don't trust them, so we should not list them + as users from that domain can't login */ + if (ads_pull_uint32(ads, msg, "trustDirection", &direction) && + direction == 1) { + continue; + } + + (*names)[i] = ads_pull_string(ads, mem_ctx, msg, "name"); + (*alt_names)[i] = ads_pull_string(ads, mem_ctx, msg, "flatname"); + + if ((*alt_names)[i] && (*alt_names)[i][0]) { + /* we prefer the flatname as the primary name + for consistency with RPC */ + char *name = (*alt_names)[i]; + (*alt_names)[i] = (*names)[i]; + (*names)[i] = name; + } if (ads_pull_sid(ads, msg, "securityIdentifier", &(*sids)[i])) { i++; } @@ -1562,7 +1753,7 @@ ADS_STATUS ads_domain_sid(ADS_STRUCT *ads, DOM_SID *sid) void *res; ADS_STATUS rc; - rc = ads_do_search(ads, ads->bind_path, LDAP_SCOPE_BASE, "(objectclass=*)", + rc = ads_do_search(ads, ads->config.bind_path, LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); if (!ADS_ERR_OK(rc)) return rc; if (!ads_pull_sid(ads, res, "objectSid", sid)) { @@ -1573,4 +1764,66 @@ ADS_STATUS ads_domain_sid(ADS_STRUCT *ads, DOM_SID *sid) return ADS_SUCCESS; } +/* this is rather complex - we need to find the allternate (netbios) name + for the domain, but there isn't a simple query to do this. Instead + we look for the principle names on the DCs account and find one that has + the right form, then extract the netbios name of the domain from that +*/ +ADS_STATUS ads_workgroup_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char **workgroup) +{ + char *exp; + ADS_STATUS rc; + char **principles; + char *prefix; + int prefix_length; + int i; + void *res; + const char *attrs[] = {"servicePrincipalName", NULL}; + + (*workgroup) = NULL; + + asprintf(&exp, "(&(objectclass=computer)(dnshostname=%s.%s))", + ads->config.ldap_server_name, ads->config.realm); + rc = ads_search(ads, &res, exp, attrs); + free(exp); + + if (!ADS_ERR_OK(rc)) { + return rc; + } + + principles = ads_pull_strings(ads, mem_ctx, res, "servicePrincipalName"); + + ads_msgfree(ads, res); + + if (!principles) { + return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); + } + + asprintf(&prefix, "HOST/%s.%s/", + ads->config.ldap_server_name, + ads->config.realm); + + prefix_length = strlen(prefix); + + for (i=0;principles[i]; i++) { + if (strncasecmp(principles[i], prefix, prefix_length) == 0 && + strcasecmp(ads->config.realm, principles[i]+prefix_length) != 0 && + !strchr(principles[i]+prefix_length, '.')) { + /* found an alternate (short) name for the domain. */ + DEBUG(3,("Found alternate name '%s' for realm '%s'\n", + principles[i]+prefix_length, + ads->config.realm)); + (*workgroup) = talloc_strdup(mem_ctx, principles[i]+prefix_length); + break; + } + } + free(prefix); + + if (!*workgroup) { + return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); + } + + return ADS_SUCCESS; +} + #endif diff --git a/source3/libads/ldap_user.c b/source3/libads/ldap_user.c index b6e3d189c5..b6fef24b5c 100644 --- a/source3/libads/ldap_user.c +++ b/source3/libads/ldap_user.c @@ -55,10 +55,10 @@ ADS_STATUS ads_add_user_acct(ADS_STRUCT *ads, const char *user, status = ADS_ERROR(LDAP_NO_MEMORY); - if (!(upn = talloc_asprintf(ctx, "%s@%s", user, ads->realm))) + if (!(upn = talloc_asprintf(ctx, "%s@%s", user, ads->config.realm))) goto done; if (!(new_dn = talloc_asprintf(ctx, "cn=%s,cn=Users,%s", name, - ads->bind_path))) + ads->config.bind_path))) goto done; if (!(controlstr = talloc_asprintf(ctx, "%u", UF_NORMAL_ACCOUNT))) goto done; @@ -94,7 +94,7 @@ ADS_STATUS ads_add_group_acct(ADS_STRUCT *ads, const char *group, status = ADS_ERROR(LDAP_NO_MEMORY); if (!(new_dn = talloc_asprintf(ctx, "cn=%s,cn=Users,%s", group, - ads->bind_path))) + ads->config.bind_path))) goto done; if (!(mods = ads_init_mods(ctx))) goto done; diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 1b55453cac..81dedb0a81 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -77,7 +77,7 @@ ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) /* we need to fetch a service ticket as the ldap user in the servers realm, regardless of our realm */ - asprintf(&sname, "ldap/%s@%s", ads->ldap_server_name, ads->server_realm); + asprintf(&sname, "ldap/%s@%s", ads->config.ldap_server_name, ads->config.realm); krb5_init_context(&ctx); krb5_set_default_tgs_ktypes(ctx, enc_types); krb5_parse_name(ctx, sname, &principal); @@ -163,7 +163,7 @@ ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) gss_release_buffer(&minor_status, &output_token); - output_token.value = malloc(strlen(ads->bind_path) + 8); + output_token.value = malloc(strlen(ads->config.bind_path) + 8); p = output_token.value; *p++ = 1; /* no sign or seal */ @@ -171,9 +171,10 @@ ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) *p++ = max_msg_size>>16; *p++ = max_msg_size>>8; *p++ = max_msg_size; - snprintf(p, strlen(ads->bind_path)+4, "dn:%s", ads->bind_path); + snprintf(p, strlen(ads->config.bind_path)+4, "dn:%s", ads->config.bind_path); + p += strlen(ads->config.bind_path); - output_token.length = strlen(ads->bind_path) + 8; + output_token.length = strlen(ads->config.bind_path) + 8; gss_rc = gss_wrap(&minor_status, context_handle,0,GSS_C_QOP_DEFAULT, &output_token, &conf_state, diff --git a/source3/libads/util.c b/source3/libads/util.c index d48eb10b71..b10b130a31 100644 --- a/source3/libads/util.c +++ b/source3/libads/util.c @@ -39,7 +39,7 @@ ADS_STATUS ads_change_trust_account_password(ADS_STRUCT *ads, char *host_princip new_password = strdup(tmp_password); asprintf(&service_principal, "HOST/%s", host_principal); - ret = kerberos_set_password(ads->kdc_server, host_principal, password, + ret = kerberos_set_password(ads->auth.kdc_server, host_principal, password, service_principal, new_password); if (!secrets_store_machine_password(new_password)) { -- cgit From 2d05704d0e4b553d881f4e2563b2e71a9e1457da Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Tue, 20 Aug 2002 18:43:59 +0000 Subject: fix irix compile errors - cannot initialize array in declaration statement with non-const values - strsep not defined (This used to be commit a5c59b2cd10016ecbd931531602ad1cb3660bbf9) --- source3/libads/ldap.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 2672489482..f0c4ad9040 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -826,7 +826,11 @@ static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, ADS_STATUS ads_mod_str(TALLOC_CTX *ctx, ADS_MODLIST *mods, const char *name, const char *val) { - const char *values[2] = {val, NULL}; + const char *values[2]; + + values[0] = val; + values[1] = NULL; + if (!val) return ads_modlist_add(ctx, mods, LDAP_MOD_DELETE, name, NULL); return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE, name, @@ -861,7 +865,10 @@ ADS_STATUS ads_mod_strlist(TALLOC_CTX *ctx, ADS_MODLIST *mods, static ADS_STATUS ads_mod_ber(TALLOC_CTX *ctx, ADS_MODLIST *mods, const char *name, const struct berval *val) { - const struct berval *values[2] = {val, NULL}; + const struct berval *values[2]; + + values[0] = val; + values[1] = NULL; if (!val) return ads_modlist_add(ctx, mods, LDAP_MOD_DELETE, name, NULL); return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE|LDAP_MOD_BVALUES, -- cgit From dcd029169424d8846c1fbb0b1527516a4a026b27 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 30 Aug 2002 06:59:57 +0000 Subject: convert the LDAP/SASL code to use GSS-SPNEGO if possible we now do this: - look for suported SASL mechanisms on the LDAP server - choose GSS-SPNEGO if possible - within GSS-SPNEGO choose KRB5 if we can do a kinit - otherwise use NTLMSSP This change also means that we no longer rely on having a gssapi library to do ADS. todo: - add TLS/SSL support over LDAP - change to using LDAP/SSL for password change in ADS (This used to be commit b04e91f660d3b26d23044075d4a7e707eb41462d) --- source3/libads/ldap.c | 7 +- source3/libads/sasl.c | 248 ++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 221 insertions(+), 34 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index f0c4ad9040..2cfbedc6d4 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -226,7 +226,7 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) /* try via DNS */ if (ads_try_dns(ads)) { goto got_connection; - } + } /* try via netbios lookups */ if (!lp_disable_netbios() && ads_try_netbios(ads)) { @@ -274,11 +274,6 @@ got_connection: } #endif - if (ads->auth.password) { - if ((code = ads_kinit_password(ads))) - return ADS_ERROR_KRB5(code); - } - if (ads->auth.no_bind) { return ADS_SUCCESS; } diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 81dedb0a81..12a5722319 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -22,37 +22,192 @@ #ifdef HAVE_ADS -#if USE_CYRUS_SASL -/* - this is a minimal interact function, just enough for SASL to talk - GSSAPI/kerberos to W2K - Error handling is a bit of a problem. I can't see how to get Cyrus-sasl - to give sensible errors +/* + perform a LDAP/SASL/SPNEGO/NTLMSSP bind (just how many layers can + we fit on one socket??) */ -static int sasl_interact(LDAP *ld,unsigned flags,void *defaults,void *in) +static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) { - sasl_interact_t *interact = in; + const char *mechs[] = {OID_NTLMSSP, NULL}; + DATA_BLOB msg1; + DATA_BLOB blob, chal1, chal2, auth; + uint8 challenge[8]; + uint8 nthash[24], lmhash[24], sess_key[16]; + uint32 neg_flags; + struct berval cred, *scred; + ADS_STATUS status; + extern pstring global_myname; + int rc; + + neg_flags = NTLMSSP_NEGOTIATE_UNICODE | + NTLMSSP_NEGOTIATE_128 | + NTLMSSP_NEGOTIATE_NTLM; + + memset(sess_key, 0, 16); - while (interact->id != SASL_CB_LIST_END) { - interact->result = strdup(""); - interact->len = strlen(interact->result); - interact++; + /* generate the ntlmssp negotiate packet */ + msrpc_gen(&blob, "CddB", + "NTLMSSP", + NTLMSSP_NEGOTIATE, + neg_flags, + sess_key, 16); + + /* and wrap it in a SPNEGO wrapper */ + msg1 = gen_negTokenTarg(mechs, blob); + data_blob_free(&blob); + + cred.bv_val = msg1.data; + cred.bv_len = msg1.length; + + rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred); + if (rc != LDAP_SASL_BIND_IN_PROGRESS) { + status = ADS_ERROR(rc); + goto failed; } - - return LDAP_SUCCESS; + + blob = data_blob(scred->bv_val, scred->bv_len); + + /* the server gives us back two challenges */ + if (!spnego_parse_challenge(blob, &chal1, &chal2)) { + DEBUG(3,("Failed to parse challenges\n")); + status = ADS_ERROR(LDAP_OPERATIONS_ERROR); + goto failed; + } + + data_blob_free(&blob); + + /* encrypt the password with the challenge */ + memcpy(challenge, chal1.data + 24, 8); + SMBencrypt(ads->auth.password, challenge,lmhash); + SMBNTencrypt(ads->auth.password, challenge,nthash); + + data_blob_free(&chal1); + data_blob_free(&chal2); + + /* this generates the actual auth packet */ + msrpc_gen(&blob, "CdBBUUUBd", + "NTLMSSP", + NTLMSSP_AUTH, + lmhash, 24, + nthash, 24, + lp_workgroup(), + ads->auth.user_name, + global_myname, + sess_key, 16, + neg_flags); + + /* wrap it in SPNEGO */ + auth = spnego_gen_auth(blob); + + data_blob_free(&blob); + + /* now send the auth packet and we should be done */ + cred.bv_val = auth.data; + cred.bv_len = auth.length; + + rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred); + + return ADS_ERROR(rc); + +failed: + return status; +} + +/* + perform a LDAP/SASL/SPNEGO/KRB5 bind +*/ +static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *principal) +{ + DATA_BLOB blob; + struct berval cred, *scred; + int rc; + + blob = spnego_gen_negTokenTarg(principal); + + if (!blob.data) { + return ADS_ERROR(LDAP_OPERATIONS_ERROR); + } + + /* now send the auth packet and we should be done */ + cred.bv_val = blob.data; + cred.bv_len = blob.length; + + rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred); + + data_blob_free(&blob); + + return ADS_ERROR(rc); } + +/* + this performs a SASL/SPNEGO bind +*/ +static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) +{ + struct berval *scred; + int rc, i; + ADS_STATUS status; + DATA_BLOB blob; + char *principal; + char *OIDs[ASN1_MAX_OIDS]; + BOOL got_kerberos_mechanism = False; + + rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", NULL, NULL, NULL, &scred); + + if (rc != LDAP_SASL_BIND_IN_PROGRESS) { + status = ADS_ERROR(rc); + goto failed; + } + + blob = data_blob(scred->bv_val, scred->bv_len); + +#if 0 + file_save("sasl_spnego.dat", blob.data, blob.length); #endif + /* the server sent us the first part of the SPNEGO exchange in the negprot + reply */ + if (!spnego_parse_negTokenInit(blob, OIDs, &principal)) { + data_blob_free(&blob); + status = ADS_ERROR(LDAP_OPERATIONS_ERROR); + goto failed; + } + data_blob_free(&blob); + + /* make sure the server understands kerberos */ + for (i=0;OIDs[i];i++) { + DEBUG(3,("got OID=%s\n", OIDs[i])); + if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 || + strcmp(OIDs[i], OID_KERBEROS5) == 0) { + got_kerberos_mechanism = True; + } + free(OIDs[i]); + } + DEBUG(3,("got principal=%s\n", principal)); + if (got_kerberos_mechanism && ads_kinit_password(ads) == 0) { + return ads_sasl_spnego_krb5_bind(ads, principal); + } + + /* lets do NTLMSSP ... this has the big advantage that we don't need + to sync clocks, and we don't rely on special versions of the krb5 + library for HMAC_MD4 encryption */ + return ads_sasl_spnego_ntlmssp_bind(ads); + +failed: + return status; +} + +#ifdef HAVE_GSSAPI #define MAX_GSS_PASSES 3 /* this performs a SASL/gssapi bind we avoid using cyrus-sasl to make Samba more robust. cyrus-sasl is very dependent on correctly configured DNS whereas this routine is much less fragile - see RFC2078 for details + see RFC2078 and RFC2222 for details */ -ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) +static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) { int minor_status; gss_name_t serv_name; @@ -68,6 +223,7 @@ ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) uint8 *p; uint32 max_msg_size; char *sname; + unsigned sec_layer; ADS_STATUS status; krb5_principal principal; krb5_context ctx; @@ -159,22 +315,25 @@ ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) p = (uint8 *)output_token.value; + file_save("sasl_gssapi.dat", output_token.value, output_token.length); + max_msg_size = (p[1]<<16) | (p[2]<<8) | p[3]; + sec_layer = *p; gss_release_buffer(&minor_status, &output_token); output_token.value = malloc(strlen(ads->config.bind_path) + 8); p = output_token.value; - *p++ = 1; /* no sign or seal */ + *p++ = 1; /* no sign & seal selection */ /* choose the same size as the server gave us */ *p++ = max_msg_size>>16; *p++ = max_msg_size>>8; *p++ = max_msg_size; snprintf(p, strlen(ads->config.bind_path)+4, "dn:%s", ads->config.bind_path); - p += strlen(ads->config.bind_path); + p += strlen(p); - output_token.length = strlen(ads->config.bind_path) + 8; + output_token.length = PTR_DIFF(p, output_token.value); gss_rc = gss_wrap(&minor_status, context_handle,0,GSS_C_QOP_DEFAULT, &output_token, &conf_state, @@ -198,18 +357,51 @@ ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) failed: return status; } +#endif + +/* mapping between SASL mechanisms and functions */ +static struct { + const char *name; + ADS_STATUS (*fn)(ADS_STRUCT *); +} sasl_mechanisms[] = { + {"GSS-SPNEGO", ads_sasl_spnego_bind}, +#ifdef HAVE_GSSAPI + {"GSSAPI", ads_sasl_gssapi_bind}, /* doesn't work with .NET RC1. No idea why */ +#endif + {NULL, NULL} +}; ADS_STATUS ads_sasl_bind(ADS_STRUCT *ads) { -#if USE_CYRUS_SASL - int rc; - rc = ldap_sasl_interactive_bind_s(ads->ld, NULL, NULL, NULL, NULL, - LDAP_SASL_QUIET, - sasl_interact, NULL); - return ADS_ERROR(rc); -#else - return ads_sasl_gssapi_bind(ads); -#endif + const char *attrs[] = {"supportedSASLMechanisms", NULL}; + char **values; + ADS_STATUS status; + int i, j; + void *res; + + /* get a list of supported SASL mechanisms */ + status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); + if (!ADS_ERR_OK(status)) return status; + + values = ldap_get_values(ads->ld, res, "supportedSASLMechanisms"); + + /* try our supported mechanisms in order */ + for (i=0;sasl_mechanisms[i].name;i++) { + /* see if the server supports it */ + for (j=0;values && values[j];j++) { + if (strcmp(values[j], sasl_mechanisms[i].name) == 0) { + DEBUG(4,("Found SASL mechanism %s\n", values[j])); + status = sasl_mechanisms[i].fn(ads); + ldap_value_free(values); + ldap_msgfree(res); + return status; + } + } + } + + ldap_value_free(values); + ldap_msgfree(res); + return ADS_ERROR(LDAP_AUTH_METHOD_NOT_SUPPORTED); } #endif -- cgit From 4aad4d7c73dcf8d1d0e932c21cae49a3700caf01 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 6 Sep 2002 10:39:34 +0000 Subject: Add some DEBUG()s to some libads failure modes. (This used to be commit ad3c8da13b9d510f78fd56364cd0987de88a9b9f) --- source3/libads/ldap.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 2cfbedc6d4..428fc02065 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -608,14 +608,17 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, char *utf8_exp, *utf8_path, **search_attrs = NULL; TALLOC_CTX *ctx; - if (!(ctx = talloc_init())) + if (!(ctx = talloc_init())) { + DEBUG(1,("ads_do_search: talloc_init() failed!")); return ADS_ERROR(LDAP_NO_MEMORY); + } /* 0 means the conversion worked but the result was empty so we only fail if it's negative. In any case, it always at least nulls out the dest */ if ((push_utf8_talloc(ctx, &utf8_exp, exp) < 0) || (push_utf8_talloc(ctx, &utf8_path, bind_path) < 0)) { + DEBUG(1,("ads_do_search: push_utf8_talloc() failed!")); rc = LDAP_NO_MEMORY; goto done; } @@ -627,6 +630,7 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, /* if (!(search_attrs = ads_push_strvals(ctx, attrs))) */ if (!(str_list_copy(&search_attrs, attrs))) { + DEBUG(1,("ads_do_search: str_list_copy() failed!")); rc = LDAP_NO_MEMORY; goto done; } -- cgit From eec38ee3bb4bceeaa82abf8df1cce92b6a5781ce Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 6 Sep 2002 11:46:59 +0000 Subject: Patch from "Stefan (metze) Metzmacher" to extend the ADS_STATUS system to include NTSTATUS, and to provide a better general infrustructure for his sam_ads work. I've also added some extra failure mode DEBUG()s to parts of the code. NOTE: The ADS_ERR_OK() macro is rather sensitive to braketing issues - without the final set of brakets, the test is essentially inverted - causing some intersting 'error = success' messages... Andrew Bartlett (This used to be commit 5b9a7ab901bc311f3ad08462a8a68d133c34a8b4) --- source3/libads/ads_status.c | 48 +++++++++++++++++++++++++++++++++++++-------- source3/libads/ldap.c | 2 ++ 2 files changed, 42 insertions(+), 8 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_status.c b/source3/libads/ads_status.c index 2d1830435f..d85f9c9b58 100644 --- a/source3/libads/ads_status.c +++ b/source3/libads/ads_status.c @@ -30,19 +30,49 @@ ADS_STATUS ads_build_error(enum ads_error_type etype, int rc, int minor_status) { ADS_STATUS ret; - ret.error_type = etype; - ret.rc = rc; + + if (etype == ADS_ERROR_NT) { + DEBUG(0,("don't use ads_build_error with ADS_ERROR_NT!\n")); + ret.err.rc = -1; + ret.error_type = ADS_ERROR_SYSTEM; + ret.minor_status = 0; + return ret; + } + + ret.err.rc = rc; + ret.error_type = etype; ret.minor_status = minor_status; return ret; } +ADS_STATUS ads_build_nt_error(enum ads_error_type etype, + NTSTATUS nt_status) +{ + ADS_STATUS ret; + + if (etype != ADS_ERROR_NT) { + DEBUG(0,("don't use ads_build_nt_error without ADS_ERROR_NT!\n")); + ret.err.rc = -1; + ret.error_type = ADS_ERROR_SYSTEM; + ret.minor_status = 0; + return ret; + } + ret.err.nt_status = nt_status; + ret.error_type = etype; + ret.minor_status = 0; + return ret; +} + /* do a rough conversion between ads error codes and NT status codes we'll need to fill this in more */ -NTSTATUS ads_ntstatus(ADS_STATUS rc) +NTSTATUS ads_ntstatus(ADS_STATUS status) { - if (ADS_ERR_OK(rc)) return NT_STATUS_OK; + if (status.error_type == ADS_ERROR_NT){ + return status.err.nt_status; + } + if (ADS_ERR_OK(status)) return NT_STATUS_OK; return NT_STATUS_UNSUCCESSFUL; } @@ -59,14 +89,14 @@ const char *ads_errstr(ADS_STATUS status) switch (status.error_type) { case ADS_ERROR_SYSTEM: - return strerror(status.rc); + return strerror(status.err.rc); #ifdef HAVE_LDAP case ADS_ERROR_LDAP: - return ldap_err2string(status.rc); + return ldap_err2string(status.err.rc); #endif #ifdef HAVE_KRB5 case ADS_ERROR_KRB5: - return error_message(status.rc); + return error_message(status.err.rc); #endif #ifdef HAVE_GSSAPI case ADS_ERROR_GSS: @@ -76,7 +106,7 @@ const char *ads_errstr(ADS_STATUS status) gss_buffer_desc msg1, msg2; msg1.value = NULL; msg2.value = NULL; - gss_display_status(&minor, status.rc, GSS_C_GSS_CODE, + gss_display_status(&minor, status.err.rc, GSS_C_GSS_CODE, GSS_C_NULL_OID, &msg_ctx, &msg1); gss_display_status(&minor, status.minor_status, GSS_C_MECH_CODE, GSS_C_NULL_OID, &msg_ctx, &msg2); @@ -86,6 +116,8 @@ const char *ads_errstr(ADS_STATUS status) return ret; } #endif + case ADS_ERROR_NT: + return nt_errstr(ads_ntstatus(status)); default: return "Unknown ADS error type!? (not compiled in?)"; } diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 428fc02065..2f70d3a285 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1648,6 +1648,7 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads) if (!p) { ldap_value_free(values); ldap_msgfree(res); + DEBUG(1, ("ads_server_info: returned ldap server name did not contain a ':' so was deemed invalid\n")); return ADS_ERROR(LDAP_DECODING_ERROR); } @@ -1659,6 +1660,7 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads) ldap_value_free(values); ldap_msgfree(res); SAFE_FREE(ads->config.ldap_server_name); + DEBUG(1, ("ads_server_info: returned ldap server name did not contain '$@' so was deemed invalid\n")); return ADS_ERROR(LDAP_DECODING_ERROR); } -- cgit From 7a76d0e854c0c6aef0cb6f2bc68616ad7c557e0b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 6 Sep 2002 13:46:36 +0000 Subject: Seems I missed commiting this when I added the rest of metze's ADS patch. Oh well, here it is... Andrew Bartlett (This used to be commit 7c2a667640b01a0f19ddc3515c5ca7ac43d26e25) --- source3/libads/ads_utils.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 source3/libads/ads_utils.c (limited to 'source3/libads') diff --git a/source3/libads/ads_utils.c b/source3/libads/ads_utils.c new file mode 100644 index 0000000000..1789193d7e --- /dev/null +++ b/source3/libads/ads_utils.c @@ -0,0 +1,75 @@ +/* + Unix SMB/CIFS implementation. + ads (active directory) utility library + + Copyright (C) Stefan (metze) Metzmacher 2002 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +#ifdef HAVE_ADS + + +/* +translated the ACB_CTRL Flags to UserFlags (userAccountControl) +*/ +uint32 ads_acb2uf(uint16 acb) +{ + uint32 uf = 0x00000000; + + if (acb & ACB_DISABLED) uf |= UF_ACCOUNTDISABLE; + if (acb & ACB_HOMDIRREQ) uf |= UF_HOMEDIR_REQUIRED; + if (acb & ACB_PWNOTREQ) uf |= UF_PASSWD_NOTREQD; + if (acb & ACB_TEMPDUP) uf |= UF_TEMP_DUPLICATE_ACCOUNT; + if (acb & ACB_NORMAL) uf |= UF_NORMAL_ACCOUNT; + if (acb & ACB_MNS) uf |= UF_MNS_LOGON_ACCOUNT; + if (acb & ACB_DOMTRUST) uf |= UF_INTERDOMAIN_TRUST_ACCOUNT; + if (acb & ACB_WSTRUST) uf |= UF_WORKSTATION_TRUST_ACCOUNT; + if (acb & ACB_SVRTRUST) uf |= UF_SERVER_TRUST_ACCOUNT; + if (acb & ACB_PWNOEXP) uf |= UF_DONT_EXPIRE_PASSWD; + if (acb & ACB_AUTOLOCK) uf |= UF_LOCKOUT; + + return uf; +} + +/* translated the UserFlags (userAccountControl) to ACB_CTRL Flags */ +uint16 ads_uf2acb(uint32 uf) +{ + uint16 acb = 0x0000; + + if (uf & UF_ACCOUNTDISABLE) acb |= ACB_DISABLED; + if (uf & UF_HOMEDIR_REQUIRED) acb |= ACB_HOMDIRREQ; + if (uf & UF_PASSWD_NOTREQD) acb |= ACB_PWNOTREQ; + if (uf & UF_MNS_LOGON_ACCOUNT) acb |= ACB_MNS; + if (uf & UF_DONT_EXPIRE_PASSWD) acb |= ACB_PWNOEXP; + if (uf & UF_LOCKOUT) acb |= ACB_AUTOLOCK; + + switch (uf & UF_ACCOUNT_TYPE_MASK) + { + case UF_TEMP_DUPLICATE_ACCOUNT: acb |= ACB_TEMPDUP;break; + case UF_NORMAL_ACCOUNT: acb |= ACB_NORMAL;break; + case UF_INTERDOMAIN_TRUST_ACCOUNT: acb |= ACB_DOMTRUST;break; + case UF_WORKSTATION_TRUST_ACCOUNT: acb |= ACB_WSTRUST;break; + case UF_SERVER_TRUST_ACCOUNT: acb |= ACB_SVRTRUST;break; + /*Fix Me: what should we do here? */ + default: acb |= ACB_NORMAL;break; + } + + return acb; +} + +#endif -- cgit From fffd0eb1428d9505391f8a3d2410ca0389ba113e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 17 Sep 2002 12:07:47 +0000 Subject: another const cleanup (This used to be commit 443d5ebafad46a9a62527642628aff8e5d9dc10c) --- source3/libads/ldap_printer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index 64ae8252c8..66984477b8 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -28,7 +28,7 @@ results can be used. It should be freed using ads_msgfree. */ ADS_STATUS ads_find_printer_on_server(ADS_STRUCT *ads, void **res, - char *printer, char *servername) + const char *printer, char *servername) { ADS_STATUS status; char *srv_dn, **srv_cn, *exp; -- cgit From b33681fc0b8ef7b9fa91c154f7c3117afafa349e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 17 Sep 2002 12:12:50 +0000 Subject: Add clock skew handling to our kerberos code. This allows us to cope with the DC being out of sync with the local machine. (This used to be commit 0d28d769472ea3b98ae4c8757093dfd4499f6dd1) --- source3/libads/kerberos.c | 8 ++++-- source3/libads/krb5_setpw.c | 14 +++++++--- source3/libads/ldap.c | 66 ++++++++++++++++++++++++++++++++++++--------- source3/libads/sasl.c | 7 ++--- source3/libads/util.c | 2 +- 5 files changed, 75 insertions(+), 22 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 9a486237c9..a80837cf4d 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -50,7 +50,7 @@ kerb_prompter(krb5_context ctx, void *data, simulate a kinit, putting the tgt in the default cache location remus@snapserver.com */ -int kerberos_kinit_password(const char *principal, const char *password) +int kerberos_kinit_password(const char *principal, const char *password, int time_offset) { krb5_context ctx; krb5_error_code code = 0; @@ -60,6 +60,10 @@ int kerberos_kinit_password(const char *principal, const char *password) if ((code = krb5_init_context(&ctx))) return code; + + if (time_offset != 0) { + krb5_set_real_time(ctx, time(NULL) + time_offset, 0); + } if ((code = krb5_cc_default(ctx, &cc))) { krb5_free_context(ctx); @@ -111,7 +115,7 @@ int ads_kinit_password(ADS_STRUCT *ads) int ret; asprintf(&s, "%s@%s", ads->auth.user_name, ads->auth.realm); - ret = kerberos_kinit_password(s, ads->auth.password); + ret = kerberos_kinit_password(s, ads->auth.password, ads->auth.time_offset); if (ret) { DEBUG(0,("kerberos_kinit_password %s failed: %s\n", diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index ec79a8658f..a49b6cbe3b 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -248,7 +248,8 @@ static krb5_error_code parse_setpw_reply(krb5_context context, return 0; } -ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char *newpw) +ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char *newpw, + int time_offset) { krb5_context context; krb5_auth_context auth_context = NULL; @@ -268,6 +269,10 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char return ADS_ERROR_KRB5(ret); } + if (time_offset != 0) { + krb5_set_real_time(context, time(NULL) + time_offset, 0); + } + ret = krb5_cc_default(context, &ccache); if (ret) { krb5_free_context(context); @@ -452,16 +457,17 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char ADS_STATUS kerberos_set_password(const char *kpasswd_server, const char *auth_principal, const char *auth_password, - const char *target_principal, const char *new_password) + const char *target_principal, const char *new_password, + int time_offset) { int ret; - if ((ret = kerberos_kinit_password(auth_principal, auth_password))) { + if ((ret = kerberos_kinit_password(auth_principal, auth_password, time_offset))) { DEBUG(1,("Failed kinit for principal %s (%s)\n", auth_principal, error_message(ret))); return ADS_ERROR_KRB5(ret); } - return krb5_set_password(kpasswd_server, target_principal, new_password); + return krb5_set_password(kpasswd_server, target_principal, new_password, time_offset); } diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 2f70d3a285..385a9bd93f 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -63,6 +63,7 @@ static BOOL ads_try_connect(ADS_STRUCT *ads, const char *server, unsigned port) ads->ldap_port = port; ads->ldap_ip = *interpret_addr2(srv); free(srv); + return True; } @@ -204,7 +205,6 @@ static BOOL ads_try_netbios(ADS_STRUCT *ads) ADS_STATUS ads_connect(ADS_STRUCT *ads) { int version = LDAP_VERSION3; - int code; ADS_STATUS status; ads->last_attempt = time(NULL); @@ -274,7 +274,7 @@ got_connection: } #endif - if (ads->auth.no_bind) { + if (ads->auth.flags & ADS_AUTH_NO_BIND) { return ADS_SUCCESS; } @@ -1416,7 +1416,7 @@ ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads, */ asprintf(&principal, "%s$@%s", host, ads->auth.realm); - status = krb5_set_password(ads->auth.kdc_server, principal, password); + status = krb5_set_password(ads->auth.kdc_server, principal, password, ads->auth.time_offset); free(host); free(principal); @@ -1622,6 +1622,26 @@ ADS_STATUS ads_USN(ADS_STRUCT *ads, uint32 *usn) return ADS_SUCCESS; } +/* parse a ADS timestring - typical string is + '20020917091222.0Z0' which means 09:12.22 17th September + 2002, timezone 0 */ +static time_t ads_parse_time(const char *str) +{ + struct tm tm; + + ZERO_STRUCT(tm); + + if (sscanf(str, "%4d%2d%2d%2d%2d%2d", + &tm.tm_year, &tm.tm_mon, &tm.tm_mday, + &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) { + return 0; + } + tm.tm_year -= 1900; + tm.tm_mon -= 1; + + return timegm(&tm); +} + /** * Find the servers name and realm - this can be done before authentication @@ -1632,22 +1652,36 @@ ADS_STATUS ads_USN(ADS_STRUCT *ads, uint32 *usn) **/ ADS_STATUS ads_server_info(ADS_STRUCT *ads) { - const char *attrs[] = {"ldapServiceName", NULL}; + const char *attrs[] = {"ldapServiceName", "currentTime", NULL}; ADS_STATUS status; void *res; - char **values; + char *value; char *p; + char *timestr; + TALLOC_CTX *ctx; + + if (!(ctx = talloc_init())) { + return ADS_ERROR(LDAP_NO_MEMORY); + } status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); if (!ADS_ERR_OK(status)) return status; - values = ldap_get_values(ads->ld, res, "ldapServiceName"); - if (!values || !values[0]) return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); + value = ads_pull_string(ads, ctx, res, "ldapServiceName"); + if (!value) { + return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); + } + + timestr = ads_pull_string(ads, ctx, res, "currentTime"); + if (!timestr) { + return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); + } - p = strchr(values[0], ':'); + ldap_msgfree(res); + + p = strchr(value, ':'); if (!p) { - ldap_value_free(values); - ldap_msgfree(res); + talloc_destroy(ctx); DEBUG(1, ("ads_server_info: returned ldap server name did not contain a ':' so was deemed invalid\n")); return ADS_ERROR(LDAP_DECODING_ERROR); } @@ -1657,8 +1691,7 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads) ads->config.ldap_server_name = strdup(p+1); p = strchr(ads->config.ldap_server_name, '$'); if (!p || p[1] != '@') { - ldap_value_free(values); - ldap_msgfree(res); + talloc_destroy(ctx); SAFE_FREE(ads->config.ldap_server_name); DEBUG(1, ("ads_server_info: returned ldap server name did not contain '$@' so was deemed invalid\n")); return ADS_ERROR(LDAP_DECODING_ERROR); @@ -1675,6 +1708,15 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads) DEBUG(3,("got ldap server name %s@%s\n", ads->config.ldap_server_name, ads->config.realm)); + ads->config.current_time = ads_parse_time(timestr); + + if (ads->config.current_time != 0) { + ads->auth.time_offset = ads->config.current_time - time(NULL); + DEBUG(4,("time offset is %d seconds\n", ads->auth.time_offset)); + } + + talloc_destroy(ctx); + return ADS_SUCCESS; } diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 12a5722319..c110c1d2cd 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -122,7 +122,7 @@ static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *princip struct berval cred, *scred; int rc; - blob = spnego_gen_negTokenTarg(principal); + blob = spnego_gen_negTokenTarg(principal, ads->auth.time_offset); if (!blob.data) { return ADS_ERROR(LDAP_OPERATIONS_ERROR); @@ -144,7 +144,7 @@ static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *princip */ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) { - struct berval *scred; + struct berval *scred=NULL; int rc, i; ADS_STATUS status; DATA_BLOB blob; @@ -185,7 +185,8 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) } DEBUG(3,("got principal=%s\n", principal)); - if (got_kerberos_mechanism && ads_kinit_password(ads) == 0) { + if (!(ads->auth.flags & ADS_AUTH_DISABLE_KERBEROS) && + got_kerberos_mechanism && ads_kinit_password(ads) == 0) { return ads_sasl_spnego_krb5_bind(ads, principal); } diff --git a/source3/libads/util.c b/source3/libads/util.c index b10b130a31..021f2d93e4 100644 --- a/source3/libads/util.c +++ b/source3/libads/util.c @@ -40,7 +40,7 @@ ADS_STATUS ads_change_trust_account_password(ADS_STRUCT *ads, char *host_princip asprintf(&service_principal, "HOST/%s", host_principal); ret = kerberos_set_password(ads->auth.kdc_server, host_principal, password, - service_principal, new_password); + service_principal, new_password, ads->auth.time_offset); if (!secrets_store_machine_password(new_password)) { DEBUG(1,("Failed to save machine password\n")); -- cgit From 6f67ae667aabacbfc46faadfe2bb7bbe04dd049a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 25 Sep 2002 09:32:08 +0000 Subject: Avoid a segfault in net join when you have not done an kinit, and it's falling back to NTLMSSP. We need to get the password out of the user, and this eventually does. Andrew Bartlett (This used to be commit bb518a3bae3bf91a589021fcc5b1e715247c5ded) --- source3/libads/sasl.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index c110c1d2cd..f7dd01084a 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -39,6 +39,11 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) extern pstring global_myname; int rc; + if (!ads->auth.password) { + /* No password, don't segfault below... */ + return ADS_ERROR_NT(NT_STATUS_LOGON_FAILURE); + } + neg_flags = NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_NTLM; -- cgit From b06d2abe746fb7873846e9f14bb8d3895c4290ed Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 25 Sep 2002 09:40:45 +0000 Subject: Another patch from metze, towards his work on sam_ads. See mx-ldap.sf.net for his current progress. (This used to be commit 9c62d1312fdf0aa7b1978e8bbb56fc076ba7e9d0) --- source3/libads/ads_utils.c | 98 +++++++++++++++++++++++++++++++++++++++++++++- source3/libads/ldap.c | 2 +- 2 files changed, 98 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_utils.c b/source3/libads/ads_utils.c index 1789193d7e..fc8a270021 100644 --- a/source3/libads/ads_utils.c +++ b/source3/libads/ads_utils.c @@ -46,7 +46,9 @@ uint32 ads_acb2uf(uint16 acb) return uf; } -/* translated the UserFlags (userAccountControl) to ACB_CTRL Flags */ +/* +translated the UserFlags (userAccountControl) to ACB_CTRL Flags +*/ uint16 ads_uf2acb(uint32 uf) { uint16 acb = 0x0000; @@ -72,4 +74,98 @@ uint16 ads_uf2acb(uint32 uf) return acb; } +/* +get the accountType from the UserFlags +*/ +uint32 ads_uf2atype(uint32 uf) +{ + uint32 atype = 0x00000000; + + if (uf & UF_NORMAL_ACCOUNT) atype = ATYPE_NORMAL_ACCOUNT; + else if (uf & UF_TEMP_DUPLICATE_ACCOUNT) atype = ATYPE_NORMAL_ACCOUNT; + else if (uf & UF_SERVER_TRUST_ACCOUNT) atype = ATYPE_WORKSTATION_TRUST; + else if (uf & UF_WORKSTATION_TRUST_ACCOUNT) atype = ATYPE_WORKSTATION_TRUST; + else if (uf & UF_INTERDOMAIN_TRUST_ACCOUNT) atype = ATYPE_INTERDOMAIN_TRUST; + + return atype; +} + +/* +translated the GROUP_CTRL Flags to GroupType (groupType) +*/ +uint32 ads_gcb2gtype(uint16 gcb) +{ + uint32 gtype = 0x00000000; + + if (gcb & GCB_ALIAS_GROUP) gtype |= GTYPE_SECURITY_BUILTIN_LOCAL_GROUP; + else if(gcb & GCB_LOCAL_GROUP) gtype |= GTYPE_SECURITY_DOMAIN_LOCAL_GROUP; + if (gcb & GCB_GLOBAL_GROUP) gtype |= GTYPE_SECURITY_GLOBAL_GROUP; + + return gtype; +} + +/* +translated the GroupType (groupType) to GROUP_CTRL Flags +*/ +uint16 ads_gtype2gcb(uint32 gtype) +{ + uint16 gcb = 0x0000; + + switch(gtype) { + case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP: + gcb = GCB_ALIAS_GROUP; + break; + case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP: + gcb = GCB_LOCAL_GROUP; + break; + case GTYPE_SECURITY_GLOBAL_GROUP: + gcb = GCB_GLOBAL_GROUP; + break; + + case GTYPE_DISTRIBUTION_GLOBAL_GROUP: + gcb = GCB_GLOBAL_GROUP; + break; + case GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP: + gcb = GCB_LOCAL_GROUP; + break; + case GTYPE_DISTRIBUTION_UNIVERSAL_GROUP: + gcb = GCB_GLOBAL_GROUP; + break; + } + + return gcb; +} + +/* +get the accountType from the groupType +*/ +uint32 ads_gtype2atype(uint32 gtype) +{ + uint32 atype = 0x00000000; + + switch(gtype) { + case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP: + atype = ATYPE_SECURITY_LOCAL_GROUP; + break; + case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP: + atype = ATYPE_SECURITY_LOCAL_GROUP; + break; + case GTYPE_SECURITY_GLOBAL_GROUP: + atype = ATYPE_SECURITY_GLOBAL_GROUP; + break; + + case GTYPE_DISTRIBUTION_GLOBAL_GROUP: + atype = ATYPE_DISTRIBUTION_GLOBAL_GROUP; + break; + case GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP: + atype = ATYPE_DISTRIBUTION_UNIVERSAL_GROUP; + break; + case GTYPE_DISTRIBUTION_UNIVERSAL_GROUP: + atype = ATYPE_DISTRIBUTION_LOCAL_GROUP; + break; + } + + return atype; +} + #endif diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 385a9bd93f..7a0afb1a81 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -890,7 +890,7 @@ ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, ADS_MODLIST mods) non-existent attribute (but allowable for the object) to run */ LDAPControl PermitModify = { - "1.2.840.113556.1.4.1413", + ADS_PERMIT_MODIFY_OID, {0, NULL}, (char) 1}; LDAPControl *controls[2]; -- cgit From a834a73e341059be154426390304a42e4a011f72 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 25 Sep 2002 15:19:00 +0000 Subject: sync'ing up for 3.0alpha20 release (This used to be commit 65e7b5273bb58802bf0c389b77f7fcae0a1f6139) --- source3/libads/ads_status.c | 48 ++++++-- source3/libads/kerberos.c | 8 +- source3/libads/krb5_setpw.c | 14 ++- source3/libads/ldap.c | 94 ++++++++++++---- source3/libads/ldap_printer.c | 2 +- source3/libads/sasl.c | 254 +++++++++++++++++++++++++++++++++++++----- source3/libads/util.c | 2 +- 7 files changed, 356 insertions(+), 66 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_status.c b/source3/libads/ads_status.c index 2d1830435f..d85f9c9b58 100644 --- a/source3/libads/ads_status.c +++ b/source3/libads/ads_status.c @@ -30,19 +30,49 @@ ADS_STATUS ads_build_error(enum ads_error_type etype, int rc, int minor_status) { ADS_STATUS ret; - ret.error_type = etype; - ret.rc = rc; + + if (etype == ADS_ERROR_NT) { + DEBUG(0,("don't use ads_build_error with ADS_ERROR_NT!\n")); + ret.err.rc = -1; + ret.error_type = ADS_ERROR_SYSTEM; + ret.minor_status = 0; + return ret; + } + + ret.err.rc = rc; + ret.error_type = etype; ret.minor_status = minor_status; return ret; } +ADS_STATUS ads_build_nt_error(enum ads_error_type etype, + NTSTATUS nt_status) +{ + ADS_STATUS ret; + + if (etype != ADS_ERROR_NT) { + DEBUG(0,("don't use ads_build_nt_error without ADS_ERROR_NT!\n")); + ret.err.rc = -1; + ret.error_type = ADS_ERROR_SYSTEM; + ret.minor_status = 0; + return ret; + } + ret.err.nt_status = nt_status; + ret.error_type = etype; + ret.minor_status = 0; + return ret; +} + /* do a rough conversion between ads error codes and NT status codes we'll need to fill this in more */ -NTSTATUS ads_ntstatus(ADS_STATUS rc) +NTSTATUS ads_ntstatus(ADS_STATUS status) { - if (ADS_ERR_OK(rc)) return NT_STATUS_OK; + if (status.error_type == ADS_ERROR_NT){ + return status.err.nt_status; + } + if (ADS_ERR_OK(status)) return NT_STATUS_OK; return NT_STATUS_UNSUCCESSFUL; } @@ -59,14 +89,14 @@ const char *ads_errstr(ADS_STATUS status) switch (status.error_type) { case ADS_ERROR_SYSTEM: - return strerror(status.rc); + return strerror(status.err.rc); #ifdef HAVE_LDAP case ADS_ERROR_LDAP: - return ldap_err2string(status.rc); + return ldap_err2string(status.err.rc); #endif #ifdef HAVE_KRB5 case ADS_ERROR_KRB5: - return error_message(status.rc); + return error_message(status.err.rc); #endif #ifdef HAVE_GSSAPI case ADS_ERROR_GSS: @@ -76,7 +106,7 @@ const char *ads_errstr(ADS_STATUS status) gss_buffer_desc msg1, msg2; msg1.value = NULL; msg2.value = NULL; - gss_display_status(&minor, status.rc, GSS_C_GSS_CODE, + gss_display_status(&minor, status.err.rc, GSS_C_GSS_CODE, GSS_C_NULL_OID, &msg_ctx, &msg1); gss_display_status(&minor, status.minor_status, GSS_C_MECH_CODE, GSS_C_NULL_OID, &msg_ctx, &msg2); @@ -86,6 +116,8 @@ const char *ads_errstr(ADS_STATUS status) return ret; } #endif + case ADS_ERROR_NT: + return nt_errstr(ads_ntstatus(status)); default: return "Unknown ADS error type!? (not compiled in?)"; } diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 9a486237c9..a80837cf4d 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -50,7 +50,7 @@ kerb_prompter(krb5_context ctx, void *data, simulate a kinit, putting the tgt in the default cache location remus@snapserver.com */ -int kerberos_kinit_password(const char *principal, const char *password) +int kerberos_kinit_password(const char *principal, const char *password, int time_offset) { krb5_context ctx; krb5_error_code code = 0; @@ -60,6 +60,10 @@ int kerberos_kinit_password(const char *principal, const char *password) if ((code = krb5_init_context(&ctx))) return code; + + if (time_offset != 0) { + krb5_set_real_time(ctx, time(NULL) + time_offset, 0); + } if ((code = krb5_cc_default(ctx, &cc))) { krb5_free_context(ctx); @@ -111,7 +115,7 @@ int ads_kinit_password(ADS_STRUCT *ads) int ret; asprintf(&s, "%s@%s", ads->auth.user_name, ads->auth.realm); - ret = kerberos_kinit_password(s, ads->auth.password); + ret = kerberos_kinit_password(s, ads->auth.password, ads->auth.time_offset); if (ret) { DEBUG(0,("kerberos_kinit_password %s failed: %s\n", diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index ec79a8658f..a49b6cbe3b 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -248,7 +248,8 @@ static krb5_error_code parse_setpw_reply(krb5_context context, return 0; } -ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char *newpw) +ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char *newpw, + int time_offset) { krb5_context context; krb5_auth_context auth_context = NULL; @@ -268,6 +269,10 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char return ADS_ERROR_KRB5(ret); } + if (time_offset != 0) { + krb5_set_real_time(context, time(NULL) + time_offset, 0); + } + ret = krb5_cc_default(context, &ccache); if (ret) { krb5_free_context(context); @@ -452,16 +457,17 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char ADS_STATUS kerberos_set_password(const char *kpasswd_server, const char *auth_principal, const char *auth_password, - const char *target_principal, const char *new_password) + const char *target_principal, const char *new_password, + int time_offset) { int ret; - if ((ret = kerberos_kinit_password(auth_principal, auth_password))) { + if ((ret = kerberos_kinit_password(auth_principal, auth_password, time_offset))) { DEBUG(1,("Failed kinit for principal %s (%s)\n", auth_principal, error_message(ret))); return ADS_ERROR_KRB5(ret); } - return krb5_set_password(kpasswd_server, target_principal, new_password); + return krb5_set_password(kpasswd_server, target_principal, new_password, time_offset); } diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 2672489482..7a0afb1a81 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -63,6 +63,7 @@ static BOOL ads_try_connect(ADS_STRUCT *ads, const char *server, unsigned port) ads->ldap_port = port; ads->ldap_ip = *interpret_addr2(srv); free(srv); + return True; } @@ -204,7 +205,6 @@ static BOOL ads_try_netbios(ADS_STRUCT *ads) ADS_STATUS ads_connect(ADS_STRUCT *ads) { int version = LDAP_VERSION3; - int code; ADS_STATUS status; ads->last_attempt = time(NULL); @@ -226,7 +226,7 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) /* try via DNS */ if (ads_try_dns(ads)) { goto got_connection; - } + } /* try via netbios lookups */ if (!lp_disable_netbios() && ads_try_netbios(ads)) { @@ -274,12 +274,7 @@ got_connection: } #endif - if (ads->auth.password) { - if ((code = ads_kinit_password(ads))) - return ADS_ERROR_KRB5(code); - } - - if (ads->auth.no_bind) { + if (ads->auth.flags & ADS_AUTH_NO_BIND) { return ADS_SUCCESS; } @@ -613,14 +608,17 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, char *utf8_exp, *utf8_path, **search_attrs = NULL; TALLOC_CTX *ctx; - if (!(ctx = talloc_init())) + if (!(ctx = talloc_init())) { + DEBUG(1,("ads_do_search: talloc_init() failed!")); return ADS_ERROR(LDAP_NO_MEMORY); + } /* 0 means the conversion worked but the result was empty so we only fail if it's negative. In any case, it always at least nulls out the dest */ if ((push_utf8_talloc(ctx, &utf8_exp, exp) < 0) || (push_utf8_talloc(ctx, &utf8_path, bind_path) < 0)) { + DEBUG(1,("ads_do_search: push_utf8_talloc() failed!")); rc = LDAP_NO_MEMORY; goto done; } @@ -632,6 +630,7 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, /* if (!(search_attrs = ads_push_strvals(ctx, attrs))) */ if (!(str_list_copy(&search_attrs, attrs))) { + DEBUG(1,("ads_do_search: str_list_copy() failed!")); rc = LDAP_NO_MEMORY; goto done; } @@ -826,7 +825,11 @@ static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, ADS_STATUS ads_mod_str(TALLOC_CTX *ctx, ADS_MODLIST *mods, const char *name, const char *val) { - const char *values[2] = {val, NULL}; + const char *values[2]; + + values[0] = val; + values[1] = NULL; + if (!val) return ads_modlist_add(ctx, mods, LDAP_MOD_DELETE, name, NULL); return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE, name, @@ -861,7 +864,10 @@ ADS_STATUS ads_mod_strlist(TALLOC_CTX *ctx, ADS_MODLIST *mods, static ADS_STATUS ads_mod_ber(TALLOC_CTX *ctx, ADS_MODLIST *mods, const char *name, const struct berval *val) { - const struct berval *values[2] = {val, NULL}; + const struct berval *values[2]; + + values[0] = val; + values[1] = NULL; if (!val) return ads_modlist_add(ctx, mods, LDAP_MOD_DELETE, name, NULL); return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE|LDAP_MOD_BVALUES, @@ -884,7 +890,7 @@ ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, ADS_MODLIST mods) non-existent attribute (but allowable for the object) to run */ LDAPControl PermitModify = { - "1.2.840.113556.1.4.1413", + ADS_PERMIT_MODIFY_OID, {0, NULL}, (char) 1}; LDAPControl *controls[2]; @@ -1410,7 +1416,7 @@ ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads, */ asprintf(&principal, "%s$@%s", host, ads->auth.realm); - status = krb5_set_password(ads->auth.kdc_server, principal, password); + status = krb5_set_password(ads->auth.kdc_server, principal, password, ads->auth.time_offset); free(host); free(principal); @@ -1616,6 +1622,26 @@ ADS_STATUS ads_USN(ADS_STRUCT *ads, uint32 *usn) return ADS_SUCCESS; } +/* parse a ADS timestring - typical string is + '20020917091222.0Z0' which means 09:12.22 17th September + 2002, timezone 0 */ +static time_t ads_parse_time(const char *str) +{ + struct tm tm; + + ZERO_STRUCT(tm); + + if (sscanf(str, "%4d%2d%2d%2d%2d%2d", + &tm.tm_year, &tm.tm_mon, &tm.tm_mday, + &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) { + return 0; + } + tm.tm_year -= 1900; + tm.tm_mon -= 1; + + return timegm(&tm); +} + /** * Find the servers name and realm - this can be done before authentication @@ -1626,22 +1652,37 @@ ADS_STATUS ads_USN(ADS_STRUCT *ads, uint32 *usn) **/ ADS_STATUS ads_server_info(ADS_STRUCT *ads) { - const char *attrs[] = {"ldapServiceName", NULL}; + const char *attrs[] = {"ldapServiceName", "currentTime", NULL}; ADS_STATUS status; void *res; - char **values; + char *value; char *p; + char *timestr; + TALLOC_CTX *ctx; + + if (!(ctx = talloc_init())) { + return ADS_ERROR(LDAP_NO_MEMORY); + } status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); if (!ADS_ERR_OK(status)) return status; - values = ldap_get_values(ads->ld, res, "ldapServiceName"); - if (!values || !values[0]) return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); + value = ads_pull_string(ads, ctx, res, "ldapServiceName"); + if (!value) { + return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); + } + + timestr = ads_pull_string(ads, ctx, res, "currentTime"); + if (!timestr) { + return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); + } + + ldap_msgfree(res); - p = strchr(values[0], ':'); + p = strchr(value, ':'); if (!p) { - ldap_value_free(values); - ldap_msgfree(res); + talloc_destroy(ctx); + DEBUG(1, ("ads_server_info: returned ldap server name did not contain a ':' so was deemed invalid\n")); return ADS_ERROR(LDAP_DECODING_ERROR); } @@ -1650,9 +1691,9 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads) ads->config.ldap_server_name = strdup(p+1); p = strchr(ads->config.ldap_server_name, '$'); if (!p || p[1] != '@') { - ldap_value_free(values); - ldap_msgfree(res); + talloc_destroy(ctx); SAFE_FREE(ads->config.ldap_server_name); + DEBUG(1, ("ads_server_info: returned ldap server name did not contain '$@' so was deemed invalid\n")); return ADS_ERROR(LDAP_DECODING_ERROR); } @@ -1667,6 +1708,15 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads) DEBUG(3,("got ldap server name %s@%s\n", ads->config.ldap_server_name, ads->config.realm)); + ads->config.current_time = ads_parse_time(timestr); + + if (ads->config.current_time != 0) { + ads->auth.time_offset = ads->config.current_time - time(NULL); + DEBUG(4,("time offset is %d seconds\n", ads->auth.time_offset)); + } + + talloc_destroy(ctx); + return ADS_SUCCESS; } diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index 64ae8252c8..66984477b8 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -28,7 +28,7 @@ results can be used. It should be freed using ads_msgfree. */ ADS_STATUS ads_find_printer_on_server(ADS_STRUCT *ads, void **res, - char *printer, char *servername) + const char *printer, char *servername) { ADS_STATUS status; char *srv_dn, **srv_cn, *exp; diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 81dedb0a81..f7dd01084a 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -22,37 +22,198 @@ #ifdef HAVE_ADS -#if USE_CYRUS_SASL -/* - this is a minimal interact function, just enough for SASL to talk - GSSAPI/kerberos to W2K - Error handling is a bit of a problem. I can't see how to get Cyrus-sasl - to give sensible errors +/* + perform a LDAP/SASL/SPNEGO/NTLMSSP bind (just how many layers can + we fit on one socket??) */ -static int sasl_interact(LDAP *ld,unsigned flags,void *defaults,void *in) +static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) { - sasl_interact_t *interact = in; + const char *mechs[] = {OID_NTLMSSP, NULL}; + DATA_BLOB msg1; + DATA_BLOB blob, chal1, chal2, auth; + uint8 challenge[8]; + uint8 nthash[24], lmhash[24], sess_key[16]; + uint32 neg_flags; + struct berval cred, *scred; + ADS_STATUS status; + extern pstring global_myname; + int rc; - while (interact->id != SASL_CB_LIST_END) { - interact->result = strdup(""); - interact->len = strlen(interact->result); - interact++; + if (!ads->auth.password) { + /* No password, don't segfault below... */ + return ADS_ERROR_NT(NT_STATUS_LOGON_FAILURE); } - - return LDAP_SUCCESS; + + neg_flags = NTLMSSP_NEGOTIATE_UNICODE | + NTLMSSP_NEGOTIATE_128 | + NTLMSSP_NEGOTIATE_NTLM; + + memset(sess_key, 0, 16); + + /* generate the ntlmssp negotiate packet */ + msrpc_gen(&blob, "CddB", + "NTLMSSP", + NTLMSSP_NEGOTIATE, + neg_flags, + sess_key, 16); + + /* and wrap it in a SPNEGO wrapper */ + msg1 = gen_negTokenTarg(mechs, blob); + data_blob_free(&blob); + + cred.bv_val = msg1.data; + cred.bv_len = msg1.length; + + rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred); + if (rc != LDAP_SASL_BIND_IN_PROGRESS) { + status = ADS_ERROR(rc); + goto failed; + } + + blob = data_blob(scred->bv_val, scred->bv_len); + + /* the server gives us back two challenges */ + if (!spnego_parse_challenge(blob, &chal1, &chal2)) { + DEBUG(3,("Failed to parse challenges\n")); + status = ADS_ERROR(LDAP_OPERATIONS_ERROR); + goto failed; + } + + data_blob_free(&blob); + + /* encrypt the password with the challenge */ + memcpy(challenge, chal1.data + 24, 8); + SMBencrypt(ads->auth.password, challenge,lmhash); + SMBNTencrypt(ads->auth.password, challenge,nthash); + + data_blob_free(&chal1); + data_blob_free(&chal2); + + /* this generates the actual auth packet */ + msrpc_gen(&blob, "CdBBUUUBd", + "NTLMSSP", + NTLMSSP_AUTH, + lmhash, 24, + nthash, 24, + lp_workgroup(), + ads->auth.user_name, + global_myname, + sess_key, 16, + neg_flags); + + /* wrap it in SPNEGO */ + auth = spnego_gen_auth(blob); + + data_blob_free(&blob); + + /* now send the auth packet and we should be done */ + cred.bv_val = auth.data; + cred.bv_len = auth.length; + + rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred); + + return ADS_ERROR(rc); + +failed: + return status; } + +/* + perform a LDAP/SASL/SPNEGO/KRB5 bind +*/ +static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *principal) +{ + DATA_BLOB blob; + struct berval cred, *scred; + int rc; + + blob = spnego_gen_negTokenTarg(principal, ads->auth.time_offset); + + if (!blob.data) { + return ADS_ERROR(LDAP_OPERATIONS_ERROR); + } + + /* now send the auth packet and we should be done */ + cred.bv_val = blob.data; + cred.bv_len = blob.length; + + rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred); + + data_blob_free(&blob); + + return ADS_ERROR(rc); +} + +/* + this performs a SASL/SPNEGO bind +*/ +static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) +{ + struct berval *scred=NULL; + int rc, i; + ADS_STATUS status; + DATA_BLOB blob; + char *principal; + char *OIDs[ASN1_MAX_OIDS]; + BOOL got_kerberos_mechanism = False; + + rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", NULL, NULL, NULL, &scred); + + if (rc != LDAP_SASL_BIND_IN_PROGRESS) { + status = ADS_ERROR(rc); + goto failed; + } + + blob = data_blob(scred->bv_val, scred->bv_len); + +#if 0 + file_save("sasl_spnego.dat", blob.data, blob.length); #endif + /* the server sent us the first part of the SPNEGO exchange in the negprot + reply */ + if (!spnego_parse_negTokenInit(blob, OIDs, &principal)) { + data_blob_free(&blob); + status = ADS_ERROR(LDAP_OPERATIONS_ERROR); + goto failed; + } + data_blob_free(&blob); + + /* make sure the server understands kerberos */ + for (i=0;OIDs[i];i++) { + DEBUG(3,("got OID=%s\n", OIDs[i])); + if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 || + strcmp(OIDs[i], OID_KERBEROS5) == 0) { + got_kerberos_mechanism = True; + } + free(OIDs[i]); + } + DEBUG(3,("got principal=%s\n", principal)); + if (!(ads->auth.flags & ADS_AUTH_DISABLE_KERBEROS) && + got_kerberos_mechanism && ads_kinit_password(ads) == 0) { + return ads_sasl_spnego_krb5_bind(ads, principal); + } + + /* lets do NTLMSSP ... this has the big advantage that we don't need + to sync clocks, and we don't rely on special versions of the krb5 + library for HMAC_MD4 encryption */ + return ads_sasl_spnego_ntlmssp_bind(ads); + +failed: + return status; +} + +#ifdef HAVE_GSSAPI #define MAX_GSS_PASSES 3 /* this performs a SASL/gssapi bind we avoid using cyrus-sasl to make Samba more robust. cyrus-sasl is very dependent on correctly configured DNS whereas this routine is much less fragile - see RFC2078 for details + see RFC2078 and RFC2222 for details */ -ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) +static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) { int minor_status; gss_name_t serv_name; @@ -68,6 +229,7 @@ ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) uint8 *p; uint32 max_msg_size; char *sname; + unsigned sec_layer; ADS_STATUS status; krb5_principal principal; krb5_context ctx; @@ -159,22 +321,25 @@ ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) p = (uint8 *)output_token.value; + file_save("sasl_gssapi.dat", output_token.value, output_token.length); + max_msg_size = (p[1]<<16) | (p[2]<<8) | p[3]; + sec_layer = *p; gss_release_buffer(&minor_status, &output_token); output_token.value = malloc(strlen(ads->config.bind_path) + 8); p = output_token.value; - *p++ = 1; /* no sign or seal */ + *p++ = 1; /* no sign & seal selection */ /* choose the same size as the server gave us */ *p++ = max_msg_size>>16; *p++ = max_msg_size>>8; *p++ = max_msg_size; snprintf(p, strlen(ads->config.bind_path)+4, "dn:%s", ads->config.bind_path); - p += strlen(ads->config.bind_path); + p += strlen(p); - output_token.length = strlen(ads->config.bind_path) + 8; + output_token.length = PTR_DIFF(p, output_token.value); gss_rc = gss_wrap(&minor_status, context_handle,0,GSS_C_QOP_DEFAULT, &output_token, &conf_state, @@ -198,18 +363,51 @@ ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) failed: return status; } +#endif + +/* mapping between SASL mechanisms and functions */ +static struct { + const char *name; + ADS_STATUS (*fn)(ADS_STRUCT *); +} sasl_mechanisms[] = { + {"GSS-SPNEGO", ads_sasl_spnego_bind}, +#ifdef HAVE_GSSAPI + {"GSSAPI", ads_sasl_gssapi_bind}, /* doesn't work with .NET RC1. No idea why */ +#endif + {NULL, NULL} +}; ADS_STATUS ads_sasl_bind(ADS_STRUCT *ads) { -#if USE_CYRUS_SASL - int rc; - rc = ldap_sasl_interactive_bind_s(ads->ld, NULL, NULL, NULL, NULL, - LDAP_SASL_QUIET, - sasl_interact, NULL); - return ADS_ERROR(rc); -#else - return ads_sasl_gssapi_bind(ads); -#endif + const char *attrs[] = {"supportedSASLMechanisms", NULL}; + char **values; + ADS_STATUS status; + int i, j; + void *res; + + /* get a list of supported SASL mechanisms */ + status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); + if (!ADS_ERR_OK(status)) return status; + + values = ldap_get_values(ads->ld, res, "supportedSASLMechanisms"); + + /* try our supported mechanisms in order */ + for (i=0;sasl_mechanisms[i].name;i++) { + /* see if the server supports it */ + for (j=0;values && values[j];j++) { + if (strcmp(values[j], sasl_mechanisms[i].name) == 0) { + DEBUG(4,("Found SASL mechanism %s\n", values[j])); + status = sasl_mechanisms[i].fn(ads); + ldap_value_free(values); + ldap_msgfree(res); + return status; + } + } + } + + ldap_value_free(values); + ldap_msgfree(res); + return ADS_ERROR(LDAP_AUTH_METHOD_NOT_SUPPORTED); } #endif diff --git a/source3/libads/util.c b/source3/libads/util.c index b10b130a31..021f2d93e4 100644 --- a/source3/libads/util.c +++ b/source3/libads/util.c @@ -40,7 +40,7 @@ ADS_STATUS ads_change_trust_account_password(ADS_STRUCT *ads, char *host_princip asprintf(&service_principal, "HOST/%s", host_principal); ret = kerberos_set_password(ads->auth.kdc_server, host_principal, password, - service_principal, new_password); + service_principal, new_password, ads->auth.time_offset); if (!secrets_store_machine_password(new_password)) { DEBUG(1,("Failed to save machine password\n")); -- cgit From 55b6cebbd49be484fb6dcde2f8cb8412bb116276 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 27 Sep 2002 03:05:20 +0000 Subject: Some small cleanups to the libads code (mainly error checking), and give a sane prototype for the push_utf8_allocate code. Andrew Bartlett (This used to be commit ce00a3238ed8a82639c4d0ee3e960f7000b1a7b0) --- source3/libads/ads_status.c | 6 ++++++ source3/libads/ldap.c | 27 ++++++++++++++++++++++----- 2 files changed, 28 insertions(+), 5 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_status.c b/source3/libads/ads_status.c index d85f9c9b58..80fdb99eac 100644 --- a/source3/libads/ads_status.c +++ b/source3/libads/ads_status.c @@ -72,6 +72,12 @@ NTSTATUS ads_ntstatus(ADS_STATUS status) if (status.error_type == ADS_ERROR_NT){ return status.err.nt_status; } +#ifdef HAVE_LDAP + if ((status.error_type == ADS_ERROR_LDAP) + && (status.err.rc == LDAP_NO_MEMORY)) { + return NT_STATUS_NO_MEMORY; + } +#endif if (ADS_ERR_OK(status)) return NT_STATUS_OK; return NT_STATUS_UNSUCCESSFUL; } diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 7a0afb1a81..b4c7c3970c 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -741,7 +741,11 @@ ADS_STATUS ads_find_machine_acct(ADS_STRUCT *ads, void **res, const char *host) /* the easiest way to find a machine account anywhere in the tree is to look for hostname$ */ - asprintf(&exp, "(samAccountName=%s$)", host); + if (asprintf(&exp, "(samAccountName=%s$)", host) == -1) { + DEBUG(1, ("asprintf failed!\n")); + return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + } + status = ads_search(ads, res, exp, attrs); free(exp); return status; @@ -898,13 +902,15 @@ ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, ADS_MODLIST mods) controls[0] = &PermitModify; controls[1] = NULL; - push_utf8_allocate((void **) &utf8_dn, mod_dn); + if (push_utf8_allocate(&utf8_dn, mod_dn) == -1) { + return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + } /* find the end of the list, marked by NULL or -1 */ for(i=0;(mods[i]!=0)&&(mods[i]!=(LDAPMod *) -1);i++); /* make sure the end of the list is NULL */ mods[i] = NULL; - ret = ldap_modify_ext_s(ads->ld, utf8_dn ? utf8_dn : mod_dn, + ret = ldap_modify_ext_s(ads->ld, utf8_dn, (LDAPMod **) mods, controls, NULL); SAFE_FREE(utf8_dn); return ADS_ERROR(ret); @@ -922,7 +928,10 @@ ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ADS_MODLIST mods) int ret, i; char *utf8_dn = NULL; - push_utf8_allocate((void **) &utf8_dn, new_dn); + if (push_utf8_allocate(&utf8_dn, new_dn) == -1) { + DEBUG(1, ("ads_gen_add: push_utf8_allocate failed!")); + return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + } /* find the end of the list, marked by NULL or -1 */ for(i=0;(mods[i]!=0)&&(mods[i]!=(LDAPMod *) -1);i++); @@ -944,7 +953,11 @@ ADS_STATUS ads_del_dn(ADS_STRUCT *ads, char *del_dn) { int ret; char *utf8_dn = NULL; - push_utf8_allocate((void **) &utf8_dn, del_dn); + if (push_utf8_allocate(&utf8_dn, del_dn) == -1) { + DEBUG(1, ("ads_del_dn: push_utf8_allocate failed!")); + return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + } + ret = ldap_delete(ads->ld, utf8_dn ? utf8_dn : del_dn); return ADS_ERROR(ret); } @@ -991,6 +1004,10 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, if (!(host_upn = talloc_asprintf(ctx, "%s@%s", host_spn, ads->config.realm))) goto done; ou_str = ads_ou_string(org_unit); + if (!ou_str) { + DEBUG(1, ("ads_ou_string returned NULL (malloc failure?)\n")); + goto done; + } new_dn = talloc_asprintf(ctx, "cn=%s,%s,%s", hostname, ou_str, ads->config.bind_path); free(ou_str); -- cgit From 7e4afe538147bf31689f47232d5f2b04830dda1d Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 27 Sep 2002 12:23:47 +0000 Subject: Move a number of ADS related functions out into utility libs, so that things like metze's sam_ads can also use them. Also add error checking etc to a few more functions. Andrew Bartlett (This used to be commit c864edf4fbf8a6c37888a14b861d7c12cf503d4f) --- source3/libads/ads_ldap.c | 145 ++++++++++++++++++++++++++++++++++++++++++++ source3/libads/ads_utils.c | 20 ++++-- source3/libads/kerberos.c | 9 ++- source3/libads/ldap.c | 99 ++++++++++++++++++++++-------- source3/libads/ldap_utils.c | 90 +++++++++++++++++++++++++++ 5 files changed, 332 insertions(+), 31 deletions(-) create mode 100644 source3/libads/ads_ldap.c create mode 100644 source3/libads/ldap_utils.c (limited to 'source3/libads') diff --git a/source3/libads/ads_ldap.c b/source3/libads/ads_ldap.c new file mode 100644 index 0000000000..8c39a89762 --- /dev/null +++ b/source3/libads/ads_ldap.c @@ -0,0 +1,145 @@ +/* + Unix SMB/CIFS implementation. + + Winbind ADS backend functions + + Copyright (C) Andrew Tridgell 2001 + Copyright (C) Andrew Bartlett 2002 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#ifdef HAVE_LDAP + +/* convert a single name to a sid in a domain */ +NTSTATUS ads_name_to_sid(ADS_STRUCT *ads, + const char *name, + DOM_SID *sid, + enum SID_NAME_USE *type) +{ + const char *attrs[] = {"objectSid", "sAMAccountType", NULL}; + int count; + ADS_STATUS rc; + void *res = NULL; + char *exp; + uint32 t; + NTSTATUS status = NT_STATUS_UNSUCCESSFUL; + + if (asprintf(&exp, "(|(sAMAccountName=%s)(userPrincipalName=%s@%s))", + name, name, ads->config.realm) == -1) { + DEBUG(1,("ads_name_to_sid: asprintf failed!\n")); + status = NT_STATUS_NO_MEMORY; + goto done; + } + + rc = ads_search_retry(ads, &res, exp, attrs); + free(exp); + if (!ADS_ERR_OK(rc)) { + DEBUG(1,("name_to_sid ads_search: %s\n", ads_errstr(rc))); + goto done; + } + + count = ads_count_replies(ads, res); + if (count != 1) { + DEBUG(1,("name_to_sid: %s not found\n", name)); + goto done; + } + + if (!ads_pull_sid(ads, res, "objectSid", sid)) { + DEBUG(1,("No sid for %s !?\n", name)); + goto done; + } + + if (!ads_pull_uint32(ads, res, "sAMAccountType", &t)) { + DEBUG(1,("No sAMAccountType for %s !?\n", name)); + goto done; + } + + *type = ads_atype_map(t); + + status = NT_STATUS_OK; + + DEBUG(3,("ads name_to_sid mapped %s\n", name)); + +done: + if (res) ads_msgfree(ads, res); + + return status; +} + +/* convert a sid to a user or group name */ +NTSTATUS ads_sid_to_name(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + DOM_SID *sid, + char **name, + enum SID_NAME_USE *type) +{ + const char *attrs[] = {"userPrincipalName", + "sAMAccountName", + "sAMAccountType", NULL}; + ADS_STATUS rc; + void *msg = NULL; + char *exp = NULL; + char *sidstr = NULL; + uint32 atype; + NTSTATUS status = NT_STATUS_UNSUCCESSFUL; + + if (!(sidstr = sid_binstring(sid))) { + DEBUG(1,("ads_sid_to_name: sid_binstring failed!\n")); + status = NT_STATUS_NO_MEMORY; + goto done; + } + + if (asprintf(&exp, "(objectSid=%s)", sidstr) == -1) { + DEBUG(1,("ads_sid_to_name: asprintf failed!\n")); + status = NT_STATUS_NO_MEMORY; + goto done; + } + + rc = ads_search_retry(ads, &msg, exp, attrs); + if (!ADS_ERR_OK(rc)) { + status = ads_ntstatus(rc); + DEBUG(1,("ads_sid_to_name ads_search: %s\n", ads_errstr(rc))); + goto done; + } + + if (!ads_pull_uint32(ads, msg, "sAMAccountType", &atype)) { + goto done; + } + + *name = ads_pull_username(ads, mem_ctx, msg); + if (!*name) { + DEBUG(1,("ads_sid_to_name: ads_pull_username retuned NULL!\n")); + status = NT_STATUS_NO_MEMORY; + goto done; + } + + *type = ads_atype_map(atype); + + status = NT_STATUS_OK; + + DEBUG(3,("ads sid_to_name mapped %s\n", *name)); + +done: + if (msg) ads_msgfree(ads, msg); + + SAFE_FREE(exp); + SAFE_FREE(sidstr); + + return status; +} + +#endif diff --git a/source3/libads/ads_utils.c b/source3/libads/ads_utils.c index fc8a270021..626c177926 100644 --- a/source3/libads/ads_utils.c +++ b/source3/libads/ads_utils.c @@ -3,7 +3,8 @@ ads (active directory) utility library Copyright (C) Stefan (metze) Metzmacher 2002 - + Copyright (C) Andrew Tridgell 2001 + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or @@ -21,9 +22,6 @@ #include "includes.h" -#ifdef HAVE_ADS - - /* translated the ACB_CTRL Flags to UserFlags (userAccountControl) */ @@ -168,4 +166,16 @@ uint32 ads_gtype2atype(uint32 gtype) return atype; } -#endif +/* turn a sAMAccountType into a SID_NAME_USE */ +enum SID_NAME_USE ads_atype_map(uint32 atype) +{ + switch (atype & 0xF0000000) { + case ATYPE_GLOBAL_GROUP: + return SID_NAME_DOM_GRP; + case ATYPE_ACCOUNT: + return SID_NAME_USER; + default: + DEBUG(1,("hmm, need to map account type 0x%x\n", atype)); + } + return SID_NAME_UNKNOWN; +} diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index a80837cf4d..b586d84226 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -114,7 +114,14 @@ int ads_kinit_password(ADS_STRUCT *ads) char *s; int ret; - asprintf(&s, "%s@%s", ads->auth.user_name, ads->auth.realm); + if (asprintf(&s, "%s@%s", ads->auth.user_name, ads->auth.realm) == -1) { + return KRB5_CC_NOMEM; + } + + if (!ads->auth.password) { + return KRB5_LIBOS_CANTREADPWD; + } + ret = kerberos_kinit_password(s, ads->auth.password, ads->auth.time_offset); if (ret) { diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index b4c7c3970c..e09ffeb3f6 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1337,9 +1337,7 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) const char *attrs[] = {"ntSecurityDescriptor", "objectSid", 0}; char *exp = 0; size_t sd_size = 0; - struct berval **bvals = 0; struct berval bval = {0, NULL}; - prs_struct ps; prs_struct ps_wire; LDAPMessage *res = 0; @@ -1356,37 +1354,39 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) ret = ADS_ERROR(LDAP_SUCCESS); - asprintf(&exp, "(samAccountName=%s$)", hostname); + if (asprintf(&exp, "(samAccountName=%s$)", hostname) == -1) { + DEBUG(1, ("ads_set_machine_sd: asprintf failed!\n")); + return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + } + ret = ads_search(ads, (void *) &res, exp, attrs); if (!ADS_ERR_OK(ret)) return ret; msg = ads_first_entry(ads, res); - bvals = ldap_get_values_len(ads->ld, msg, attrs[0]); ads_pull_sid(ads, msg, attrs[1], &sid); - ads_msgfree(ads, res); -#if 0 - file_save("/tmp/sec_desc.old", bvals[0]->bv_val, bvals[0]->bv_len); -#endif - if (!(ctx = talloc_init_named("sec_io_desc"))) - return ADS_ERROR(LDAP_NO_MEMORY); - - prs_init(&ps, bvals[0]->bv_len, ctx, UNMARSHALL); - prs_append_data(&ps, bvals[0]->bv_val, bvals[0]->bv_len); - ps.data_offset = 0; - ldap_value_free_len(bvals); + if (!(ctx = talloc_init_named("sec_io_desc"))) { + ret = ADS_ERROR(LDAP_NO_MEMORY); + goto ads_set_sd_error; + } - if (!sec_io_desc("sd", &psd, &ps, 1)) + if (!ads_pull_sd(ads, ctx, msg, attrs[0], &psd)) { + ret = ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); goto ads_set_sd_error; + } status = sec_desc_add_sid(ctx, &psd, &sid, SEC_RIGHTS_FULL_CTRL, &sd_size); - if (!NT_STATUS_IS_OK(status)) + if (!NT_STATUS_IS_OK(status)) { + ret = ADS_ERROR_NT(status); goto ads_set_sd_error; + } prs_init(&ps_wire, sd_size, ctx, MARSHALL); - if (!sec_io_desc("sd_wire", &psd, &ps_wire, 1)) + if (!sec_io_desc("sd_wire", &psd, &ps_wire, 1)) { + ret = ADS_ERROR(LDAP_NO_MEMORY); goto ads_set_sd_error; + } #if 0 file_save("/tmp/sec_desc.new", ps_wire.data_p, sd_size); @@ -1398,16 +1398,11 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) ads_mod_ber(ctx, &mods, attrs[0], &bval); ret = ads_gen_mod(ads, dn, mods); - prs_mem_free(&ps); - prs_mem_free(&ps_wire); - talloc_destroy(ctx); - return ret; - ads_set_sd_error: - prs_mem_free(&ps); + ads_msgfree(ads, res); prs_mem_free(&ps_wire); talloc_destroy(ctx); - return ADS_ERROR(LDAP_NO_MEMORY); + return ret; } /** @@ -1613,6 +1608,60 @@ int ads_pull_sids(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, return count; } +/** + * pull a SEC_DESC from a ADS result + * @param ads connection to ads server + * @param mem_ctx TALLOC_CTX for allocating sid array + * @param msg Results of search + * @param field Attribute to retrieve + * @param sd Pointer to *SEC_DESC to store result (talloc()ed) + * @return boolean inidicating success +*/ +BOOL ads_pull_sd(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, + void *msg, const char *field, SEC_DESC **sd) +{ + struct berval **values; + prs_struct ps; + BOOL ret = False; + + values = ldap_get_values_len(ads->ld, msg, field); + + if (!values) return False; + + if (values[0]) { + prs_init(&ps, values[0]->bv_len, mem_ctx, UNMARSHALL); + prs_append_data(&ps, values[0]->bv_val, values[0]->bv_len); + ps.data_offset = 0; + + ret = sec_io_desc("sd", sd, &ps, 1); + } + + ldap_value_free_len(values); + return ret; +} + +/* + * in order to support usernames longer than 21 characters we need to + * use both the sAMAccountName and the userPrincipalName attributes + * It seems that not all users have the userPrincipalName attribute set + * + * @param ads connection to ads server + * @param mem_ctx TALLOC_CTX for allocating sid array + * @param msg Results of search + * @return the username + */ +char *ads_pull_username(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, void *msg) +{ + char *ret, *p; + + ret = ads_pull_string(ads, mem_ctx, msg, "userPrincipalName"); + if (ret && (p = strchr(ret, '@'))) { + *p = 0; + return ret; + } + return ads_pull_string(ads, mem_ctx, msg, "sAMAccountName"); +} + /** * find the update serial number - this is the core of the ldap cache diff --git a/source3/libads/ldap_utils.c b/source3/libads/ldap_utils.c new file mode 100644 index 0000000000..fbc9eb433f --- /dev/null +++ b/source3/libads/ldap_utils.c @@ -0,0 +1,90 @@ +/* + Unix SMB/CIFS implementation. + + Some Helpful wrappers on LDAP + + Copyright (C) Andrew Tridgell 2001 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +/* + a wrapper around ldap_search_s that retries depending on the error code + this is supposed to catch dropped connections and auto-reconnect +*/ +ADS_STATUS ads_do_search_retry(ADS_STRUCT *ads, const char *bind_path, int scope, + const char *exp, + const char **attrs, void **res) +{ + ADS_STATUS status; + int count = 3; + char *bp; + + if (!ads->ld && + time(NULL) - ads->last_attempt < ADS_RECONNECT_TIME) { + return ADS_ERROR(LDAP_SERVER_DOWN); + } + + bp = strdup(bind_path); + + while (count--) { + status = ads_do_search_all(ads, bp, scope, exp, attrs, res); + if (ADS_ERR_OK(status)) { + DEBUG(5,("Search for %s gave %d replies\n", + exp, ads_count_replies(ads, *res))); + free(bp); + return status; + } + + if (*res) ads_msgfree(ads, *res); + *res = NULL; + DEBUG(3,("Reopening ads connection to realm '%s' after error %s\n", + ads->config.realm, ads_errstr(status))); + if (ads->ld) { + ldap_unbind(ads->ld); + } + ads->ld = NULL; + status = ads_connect(ads); + if (!ADS_ERR_OK(status)) { + DEBUG(1,("ads_search_retry: failed to reconnect (%s)\n", + ads_errstr(status))); + ads_destroy(&ads); + free(bp); + return status; + } + } + free(bp); + + DEBUG(1,("ads reopen failed after error %s\n", ads_errstr(status))); + return status; +} + + +ADS_STATUS ads_search_retry(ADS_STRUCT *ads, void **res, + const char *exp, + const char **attrs) +{ + return ads_do_search_retry(ads, ads->config.bind_path, LDAP_SCOPE_SUBTREE, + exp, attrs, res); +} + +ADS_STATUS ads_search_retry_dn(ADS_STRUCT *ads, void **res, + const char *dn, + const char **attrs) +{ + return ads_do_search_retry(ads, dn, LDAP_SCOPE_BASE, + "(objectclass=*)", attrs, res); +} -- cgit From bc828246dbe367252232e5baa54ee9fc9d53ca69 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 28 Sep 2002 00:47:06 +0000 Subject: This needs to be #ifdef HAVE_LDAP. (This used to be commit 2b54a2fc2c85ea139e2acdbbc2f14b969c0c6315) --- source3/libads/ldap_utils.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap_utils.c b/source3/libads/ldap_utils.c index fbc9eb433f..9e4b8a1de9 100644 --- a/source3/libads/ldap_utils.c +++ b/source3/libads/ldap_utils.c @@ -21,6 +21,8 @@ */ #include "includes.h" + +#ifdef HAVE_LDAP /* a wrapper around ldap_search_s that retries depending on the error code this is supposed to catch dropped connections and auto-reconnect @@ -88,3 +90,4 @@ ADS_STATUS ads_search_retry_dn(ADS_STRUCT *ads, void **res, return ads_do_search_retry(ads, dn, LDAP_SCOPE_BASE, "(objectclass=*)", attrs, res); } +#endif -- cgit From 8b197158c9a7a4c881a86381f06c96d5091b5a76 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 28 Sep 2002 12:27:04 +0000 Subject: Add the beginings of sam_ads to the tree. This module, primarilly the work of "Stefan (metze) Metzmacher" , uses the Active Directory schema to store the user/group/other information. I've been testing it against a real AD server, and it is intended to work with OpenLDAP as well. I've moved a few functions around in our other libads code, which has made it easier to tap into that existing code. Also, I've made some changes to the SAM interface, I hope there are not too many objections... To ensure we don't get silly bugs in the skel module, it is now in the default compile. This way you should not forget to update it :-) Andrew Bartlett (This used to be commit 24fb0cde2f0b657df1c99474cd694438c94a566e) --- source3/libads/ads_ldap.c | 2 +- source3/libads/ads_struct.c | 1 + source3/libads/ldap.c | 43 +++++++++++++++++++++++++++++++++++++++++-- source3/libads/ldap_utils.c | 3 +++ 4 files changed, 46 insertions(+), 3 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_ldap.c b/source3/libads/ads_ldap.c index 8c39a89762..05b016539e 100644 --- a/source3/libads/ads_ldap.c +++ b/source3/libads/ads_ldap.c @@ -83,7 +83,7 @@ done: /* convert a sid to a user or group name */ NTSTATUS ads_sid_to_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, - DOM_SID *sid, + const DOM_SID *sid, char **name, enum SID_NAME_USE *type) { diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index b68c822ce3..3cdd015bf4 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -122,6 +122,7 @@ void ads_destroy(ADS_STRUCT **ads) SAFE_FREE((*ads)->server.realm); SAFE_FREE((*ads)->server.workgroup); SAFE_FREE((*ads)->server.ldap_server); + SAFE_FREE((*ads)->server.ldap_uri); SAFE_FREE((*ads)->auth.realm); SAFE_FREE((*ads)->auth.password); diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index e09ffeb3f6..1004ea229c 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -67,6 +67,29 @@ static BOOL ads_try_connect(ADS_STRUCT *ads, const char *server, unsigned port) return True; } +/* + try a connection to a given ldap server, based on URL, returning True if successful + */ +static BOOL ads_try_connect_uri(ADS_STRUCT *ads) +{ +#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) + DEBUG(5,("ads_try_connect: trying ldap server at URI '%s'\n", + ads->server.ldap_uri)); + + + if (ldap_initialize((LDAP**)&(ads->ld), ads->server.ldap_uri) == LDAP_SUCCESS) { + return True; + } + DEBUG(0, ("ldap_initialize: %s\n", strerror(errno))); + +#else + + DEBUG(1, ("no URL support in LDAP libs!\n")); +#endif + + return False; +} + /* used by the IP comparison function */ struct ldap_ip { struct in_addr ip; @@ -210,6 +233,13 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) ads->last_attempt = time(NULL); ads->ld = NULL; + /* try with a URL based server */ + + if (ads->server.ldap_uri && + ads_try_connect_uri(ads)) { + goto got_connection; + } + /* try with a user specified server */ if (ads->server.ldap_server && ads_try_connect(ads, ads->server.ldap_server, LDAP_PORT)) { @@ -278,6 +308,14 @@ got_connection: return ADS_SUCCESS; } + if (ads->auth.flags & ADS_AUTH_ANON_BIND) { + return ADS_ERROR(ldap_simple_bind_s( ads->ld, NULL, NULL)); + } + + if (ads->auth.flags & ADS_AUTH_SIMPLE_BIND) { + return ADS_ERROR(ldap_simple_bind_s( ads->ld, ads->auth.user_name, ads->auth.password)); + } + return ads_sasl_bind(ads); } @@ -1771,8 +1809,9 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads) ads->config.realm = strdup(p+2); ads->config.bind_path = ads_build_dn(ads->config.realm); - DEBUG(3,("got ldap server name %s@%s\n", - ads->config.ldap_server_name, ads->config.realm)); + DEBUG(3,("got ldap server name %s@%s, using bind path: %s\n", + ads->config.ldap_server_name, ads->config.realm, + ads->config.bind_path)); ads->config.current_time = ads_parse_time(timestr); diff --git a/source3/libads/ldap_utils.c b/source3/libads/ldap_utils.c index 9e4b8a1de9..907f7c8aff 100644 --- a/source3/libads/ldap_utils.c +++ b/source3/libads/ldap_utils.c @@ -42,6 +42,9 @@ ADS_STATUS ads_do_search_retry(ADS_STRUCT *ads, const char *bind_path, int scope bp = strdup(bind_path); + if (!bp) + return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + while (count--) { status = ads_do_search_all(ads, bp, scope, exp, attrs, res); if (ADS_ERR_OK(status)) { -- cgit From 4e73790e3a20be5c7bf8fa3b62d9d41ba246b59c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 28 Sep 2002 14:42:32 +0000 Subject: Try to compile as much as possible with only ldap, but not kerberos. (This used to be commit 9615ab10c006d8027f6a8b7dd3770eb77304dbdc) --- source3/libads/disp_sec.c | 3 --- source3/libads/krb5_setpw.c | 31 +++++++++++++++++++++++++++++++ source3/libads/ldap.c | 33 +-------------------------------- source3/libads/sasl.c | 4 +++- 4 files changed, 35 insertions(+), 36 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/disp_sec.c b/source3/libads/disp_sec.c index a930fd6fe0..a7b0bf6f07 100644 --- a/source3/libads/disp_sec.c +++ b/source3/libads/disp_sec.c @@ -20,8 +20,6 @@ #include "includes.h" -#ifdef HAVE_ADS - static struct perm_mask_str { uint32 mask; char *str; @@ -158,5 +156,4 @@ void ads_disp_sd(SEC_DESC *sd) printf("-------------- End Of Security Descriptor\n"); } -#endif diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index a49b6cbe3b..8079c0953f 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -471,4 +471,35 @@ ADS_STATUS kerberos_set_password(const char *kpasswd_server, } +/** + * Set the machine account password + * @param ads connection to ads server + * @param hostname machine whose password is being set + * @param password new password + * @return status of password change + **/ +ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads, + const char *hostname, + const char *password) +{ + ADS_STATUS status; + char *host = strdup(hostname); + char *principal; + + strlower(host); + + /* + we need to use the '$' form of the name here, as otherwise the + server might end up setting the password for a user instead + */ + asprintf(&principal, "%s$@%s", host, ads->auth.realm); + + status = krb5_set_password(ads->auth.kdc_server, principal, password, ads->auth.time_offset); + + free(host); + free(principal); + + return status; +} + #endif diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 1004ea229c..2133bf0719 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -22,7 +22,7 @@ #include "includes.h" -#ifdef HAVE_ADS +#ifdef HAVE_LDAP /** * @file ldap.c @@ -1443,37 +1443,6 @@ ads_set_sd_error: return ret; } -/** - * Set the machine account password - * @param ads connection to ads server - * @param hostname machine whose password is being set - * @param password new password - * @return status of password change - **/ -ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads, - const char *hostname, - const char *password) -{ - ADS_STATUS status; - char *host = strdup(hostname); - char *principal; - - strlower(host); - - /* - we need to use the '$' form of the name here, as otherwise the - server might end up setting the password for a user instead - */ - asprintf(&principal, "%s$@%s", host, ads->auth.realm); - - status = krb5_set_password(ads->auth.kdc_server, principal, password, ads->auth.time_offset); - - free(host); - free(principal); - - return status; -} - /** * pull the first entry from a ADS result * @param ads connection to ads server diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index f7dd01084a..aa7d99a5f7 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -20,7 +20,7 @@ #include "includes.h" -#ifdef HAVE_ADS +#ifdef HAVE_LDAP /* perform a LDAP/SASL/SPNEGO/NTLMSSP bind (just how many layers can @@ -190,10 +190,12 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) } DEBUG(3,("got principal=%s\n", principal)); +#ifdef HAVE_KRB5 if (!(ads->auth.flags & ADS_AUTH_DISABLE_KERBEROS) && got_kerberos_mechanism && ads_kinit_password(ads) == 0) { return ads_sasl_spnego_krb5_bind(ads, principal); } +#endif /* lets do NTLMSSP ... this has the big advantage that we don't need to sync clocks, and we don't rely on special versions of the krb5 -- cgit From ad8a22e570c8970247dc76defc9be2b768bd102d Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 1 Oct 2002 13:10:57 +0000 Subject: Updates from Samba HEAD: - Fix segfaults in the 'net ads' commands when no password is provided - Readd --with-ldapsam for 2.2 compatability. This conditionally compiles the old options, but the actual code is available on all ldap systems. - Fix shadow passwords (as per work with vl) - Fix sending plaintext passwords to unicode servers (again vl) - Add a bit of const to secrets.c functions - Fix some spelling and grammer by vance. - Document the -r option in smbgroupedit. There are more changes in HEAD, I'm only merging the changes I've been involved with. Andrew Bartlett (This used to be commit 83973c389355a5cc9ca74af467dfd8b5dabd2c8f) --- source3/libads/kerberos.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index a80837cf4d..b586d84226 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -114,7 +114,14 @@ int ads_kinit_password(ADS_STRUCT *ads) char *s; int ret; - asprintf(&s, "%s@%s", ads->auth.user_name, ads->auth.realm); + if (asprintf(&s, "%s@%s", ads->auth.user_name, ads->auth.realm) == -1) { + return KRB5_CC_NOMEM; + } + + if (!ads->auth.password) { + return KRB5_LIBOS_CANTREADPWD; + } + ret = kerberos_kinit_password(s, ads->auth.password, ads->auth.time_offset); if (ret) { -- cgit From f2d1f19a66ebaf9b88d23c0faa2412536cc74cda Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 1 Oct 2002 18:26:00 +0000 Subject: syncing up with HEAD. Seems to be a lot of differences creeping in (i ignored the new SAMBA stuff, but the rest of this looks like it should have been merged already). (This used to be commit 3de09e5cf1f667e410ee8b9516a956860ce7290f) --- source3/libads/ads_status.c | 6 ++ source3/libads/ads_struct.c | 1 + source3/libads/ads_utils.c | 20 +++-- source3/libads/disp_sec.c | 3 - source3/libads/krb5_setpw.c | 31 +++++++ source3/libads/ldap.c | 202 ++++++++++++++++++++++++++++++-------------- source3/libads/sasl.c | 4 +- 7 files changed, 194 insertions(+), 73 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_status.c b/source3/libads/ads_status.c index d85f9c9b58..80fdb99eac 100644 --- a/source3/libads/ads_status.c +++ b/source3/libads/ads_status.c @@ -72,6 +72,12 @@ NTSTATUS ads_ntstatus(ADS_STATUS status) if (status.error_type == ADS_ERROR_NT){ return status.err.nt_status; } +#ifdef HAVE_LDAP + if ((status.error_type == ADS_ERROR_LDAP) + && (status.err.rc == LDAP_NO_MEMORY)) { + return NT_STATUS_NO_MEMORY; + } +#endif if (ADS_ERR_OK(status)) return NT_STATUS_OK; return NT_STATUS_UNSUCCESSFUL; } diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index b68c822ce3..3cdd015bf4 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -122,6 +122,7 @@ void ads_destroy(ADS_STRUCT **ads) SAFE_FREE((*ads)->server.realm); SAFE_FREE((*ads)->server.workgroup); SAFE_FREE((*ads)->server.ldap_server); + SAFE_FREE((*ads)->server.ldap_uri); SAFE_FREE((*ads)->auth.realm); SAFE_FREE((*ads)->auth.password); diff --git a/source3/libads/ads_utils.c b/source3/libads/ads_utils.c index fc8a270021..626c177926 100644 --- a/source3/libads/ads_utils.c +++ b/source3/libads/ads_utils.c @@ -3,7 +3,8 @@ ads (active directory) utility library Copyright (C) Stefan (metze) Metzmacher 2002 - + Copyright (C) Andrew Tridgell 2001 + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or @@ -21,9 +22,6 @@ #include "includes.h" -#ifdef HAVE_ADS - - /* translated the ACB_CTRL Flags to UserFlags (userAccountControl) */ @@ -168,4 +166,16 @@ uint32 ads_gtype2atype(uint32 gtype) return atype; } -#endif +/* turn a sAMAccountType into a SID_NAME_USE */ +enum SID_NAME_USE ads_atype_map(uint32 atype) +{ + switch (atype & 0xF0000000) { + case ATYPE_GLOBAL_GROUP: + return SID_NAME_DOM_GRP; + case ATYPE_ACCOUNT: + return SID_NAME_USER; + default: + DEBUG(1,("hmm, need to map account type 0x%x\n", atype)); + } + return SID_NAME_UNKNOWN; +} diff --git a/source3/libads/disp_sec.c b/source3/libads/disp_sec.c index a930fd6fe0..a7b0bf6f07 100644 --- a/source3/libads/disp_sec.c +++ b/source3/libads/disp_sec.c @@ -20,8 +20,6 @@ #include "includes.h" -#ifdef HAVE_ADS - static struct perm_mask_str { uint32 mask; char *str; @@ -158,5 +156,4 @@ void ads_disp_sd(SEC_DESC *sd) printf("-------------- End Of Security Descriptor\n"); } -#endif diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index a49b6cbe3b..8079c0953f 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -471,4 +471,35 @@ ADS_STATUS kerberos_set_password(const char *kpasswd_server, } +/** + * Set the machine account password + * @param ads connection to ads server + * @param hostname machine whose password is being set + * @param password new password + * @return status of password change + **/ +ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads, + const char *hostname, + const char *password) +{ + ADS_STATUS status; + char *host = strdup(hostname); + char *principal; + + strlower(host); + + /* + we need to use the '$' form of the name here, as otherwise the + server might end up setting the password for a user instead + */ + asprintf(&principal, "%s$@%s", host, ads->auth.realm); + + status = krb5_set_password(ads->auth.kdc_server, principal, password, ads->auth.time_offset); + + free(host); + free(principal); + + return status; +} + #endif diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 7a0afb1a81..2133bf0719 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -22,7 +22,7 @@ #include "includes.h" -#ifdef HAVE_ADS +#ifdef HAVE_LDAP /** * @file ldap.c @@ -67,6 +67,29 @@ static BOOL ads_try_connect(ADS_STRUCT *ads, const char *server, unsigned port) return True; } +/* + try a connection to a given ldap server, based on URL, returning True if successful + */ +static BOOL ads_try_connect_uri(ADS_STRUCT *ads) +{ +#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) + DEBUG(5,("ads_try_connect: trying ldap server at URI '%s'\n", + ads->server.ldap_uri)); + + + if (ldap_initialize((LDAP**)&(ads->ld), ads->server.ldap_uri) == LDAP_SUCCESS) { + return True; + } + DEBUG(0, ("ldap_initialize: %s\n", strerror(errno))); + +#else + + DEBUG(1, ("no URL support in LDAP libs!\n")); +#endif + + return False; +} + /* used by the IP comparison function */ struct ldap_ip { struct in_addr ip; @@ -210,6 +233,13 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) ads->last_attempt = time(NULL); ads->ld = NULL; + /* try with a URL based server */ + + if (ads->server.ldap_uri && + ads_try_connect_uri(ads)) { + goto got_connection; + } + /* try with a user specified server */ if (ads->server.ldap_server && ads_try_connect(ads, ads->server.ldap_server, LDAP_PORT)) { @@ -278,6 +308,14 @@ got_connection: return ADS_SUCCESS; } + if (ads->auth.flags & ADS_AUTH_ANON_BIND) { + return ADS_ERROR(ldap_simple_bind_s( ads->ld, NULL, NULL)); + } + + if (ads->auth.flags & ADS_AUTH_SIMPLE_BIND) { + return ADS_ERROR(ldap_simple_bind_s( ads->ld, ads->auth.user_name, ads->auth.password)); + } + return ads_sasl_bind(ads); } @@ -741,7 +779,11 @@ ADS_STATUS ads_find_machine_acct(ADS_STRUCT *ads, void **res, const char *host) /* the easiest way to find a machine account anywhere in the tree is to look for hostname$ */ - asprintf(&exp, "(samAccountName=%s$)", host); + if (asprintf(&exp, "(samAccountName=%s$)", host) == -1) { + DEBUG(1, ("asprintf failed!\n")); + return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + } + status = ads_search(ads, res, exp, attrs); free(exp); return status; @@ -898,13 +940,15 @@ ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, ADS_MODLIST mods) controls[0] = &PermitModify; controls[1] = NULL; - push_utf8_allocate((void **) &utf8_dn, mod_dn); + if (push_utf8_allocate(&utf8_dn, mod_dn) == -1) { + return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + } /* find the end of the list, marked by NULL or -1 */ for(i=0;(mods[i]!=0)&&(mods[i]!=(LDAPMod *) -1);i++); /* make sure the end of the list is NULL */ mods[i] = NULL; - ret = ldap_modify_ext_s(ads->ld, utf8_dn ? utf8_dn : mod_dn, + ret = ldap_modify_ext_s(ads->ld, utf8_dn, (LDAPMod **) mods, controls, NULL); SAFE_FREE(utf8_dn); return ADS_ERROR(ret); @@ -922,7 +966,10 @@ ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ADS_MODLIST mods) int ret, i; char *utf8_dn = NULL; - push_utf8_allocate((void **) &utf8_dn, new_dn); + if (push_utf8_allocate(&utf8_dn, new_dn) == -1) { + DEBUG(1, ("ads_gen_add: push_utf8_allocate failed!")); + return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + } /* find the end of the list, marked by NULL or -1 */ for(i=0;(mods[i]!=0)&&(mods[i]!=(LDAPMod *) -1);i++); @@ -944,7 +991,11 @@ ADS_STATUS ads_del_dn(ADS_STRUCT *ads, char *del_dn) { int ret; char *utf8_dn = NULL; - push_utf8_allocate((void **) &utf8_dn, del_dn); + if (push_utf8_allocate(&utf8_dn, del_dn) == -1) { + DEBUG(1, ("ads_del_dn: push_utf8_allocate failed!")); + return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + } + ret = ldap_delete(ads->ld, utf8_dn ? utf8_dn : del_dn); return ADS_ERROR(ret); } @@ -991,6 +1042,10 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, if (!(host_upn = talloc_asprintf(ctx, "%s@%s", host_spn, ads->config.realm))) goto done; ou_str = ads_ou_string(org_unit); + if (!ou_str) { + DEBUG(1, ("ads_ou_string returned NULL (malloc failure?)\n")); + goto done; + } new_dn = talloc_asprintf(ctx, "cn=%s,%s,%s", hostname, ou_str, ads->config.bind_path); free(ou_str); @@ -1320,9 +1375,7 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) const char *attrs[] = {"ntSecurityDescriptor", "objectSid", 0}; char *exp = 0; size_t sd_size = 0; - struct berval **bvals = 0; struct berval bval = {0, NULL}; - prs_struct ps; prs_struct ps_wire; LDAPMessage *res = 0; @@ -1339,37 +1392,39 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) ret = ADS_ERROR(LDAP_SUCCESS); - asprintf(&exp, "(samAccountName=%s$)", hostname); + if (asprintf(&exp, "(samAccountName=%s$)", hostname) == -1) { + DEBUG(1, ("ads_set_machine_sd: asprintf failed!\n")); + return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + } + ret = ads_search(ads, (void *) &res, exp, attrs); if (!ADS_ERR_OK(ret)) return ret; msg = ads_first_entry(ads, res); - bvals = ldap_get_values_len(ads->ld, msg, attrs[0]); ads_pull_sid(ads, msg, attrs[1], &sid); - ads_msgfree(ads, res); -#if 0 - file_save("/tmp/sec_desc.old", bvals[0]->bv_val, bvals[0]->bv_len); -#endif - if (!(ctx = talloc_init_named("sec_io_desc"))) - return ADS_ERROR(LDAP_NO_MEMORY); - - prs_init(&ps, bvals[0]->bv_len, ctx, UNMARSHALL); - prs_append_data(&ps, bvals[0]->bv_val, bvals[0]->bv_len); - ps.data_offset = 0; - ldap_value_free_len(bvals); + if (!(ctx = talloc_init_named("sec_io_desc"))) { + ret = ADS_ERROR(LDAP_NO_MEMORY); + goto ads_set_sd_error; + } - if (!sec_io_desc("sd", &psd, &ps, 1)) + if (!ads_pull_sd(ads, ctx, msg, attrs[0], &psd)) { + ret = ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); goto ads_set_sd_error; + } status = sec_desc_add_sid(ctx, &psd, &sid, SEC_RIGHTS_FULL_CTRL, &sd_size); - if (!NT_STATUS_IS_OK(status)) + if (!NT_STATUS_IS_OK(status)) { + ret = ADS_ERROR_NT(status); goto ads_set_sd_error; + } prs_init(&ps_wire, sd_size, ctx, MARSHALL); - if (!sec_io_desc("sd_wire", &psd, &ps_wire, 1)) + if (!sec_io_desc("sd_wire", &psd, &ps_wire, 1)) { + ret = ADS_ERROR(LDAP_NO_MEMORY); goto ads_set_sd_error; + } #if 0 file_save("/tmp/sec_desc.new", ps_wire.data_p, sd_size); @@ -1381,47 +1436,11 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) ads_mod_ber(ctx, &mods, attrs[0], &bval); ret = ads_gen_mod(ads, dn, mods); - prs_mem_free(&ps); - prs_mem_free(&ps_wire); - talloc_destroy(ctx); - return ret; - ads_set_sd_error: - prs_mem_free(&ps); + ads_msgfree(ads, res); prs_mem_free(&ps_wire); talloc_destroy(ctx); - return ADS_ERROR(LDAP_NO_MEMORY); -} - -/** - * Set the machine account password - * @param ads connection to ads server - * @param hostname machine whose password is being set - * @param password new password - * @return status of password change - **/ -ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads, - const char *hostname, - const char *password) -{ - ADS_STATUS status; - char *host = strdup(hostname); - char *principal; - - strlower(host); - - /* - we need to use the '$' form of the name here, as otherwise the - server might end up setting the password for a user instead - */ - asprintf(&principal, "%s$@%s", host, ads->auth.realm); - - status = krb5_set_password(ads->auth.kdc_server, principal, password, ads->auth.time_offset); - - free(host); - free(principal); - - return status; + return ret; } /** @@ -1596,6 +1615,60 @@ int ads_pull_sids(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, return count; } +/** + * pull a SEC_DESC from a ADS result + * @param ads connection to ads server + * @param mem_ctx TALLOC_CTX for allocating sid array + * @param msg Results of search + * @param field Attribute to retrieve + * @param sd Pointer to *SEC_DESC to store result (talloc()ed) + * @return boolean inidicating success +*/ +BOOL ads_pull_sd(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, + void *msg, const char *field, SEC_DESC **sd) +{ + struct berval **values; + prs_struct ps; + BOOL ret = False; + + values = ldap_get_values_len(ads->ld, msg, field); + + if (!values) return False; + + if (values[0]) { + prs_init(&ps, values[0]->bv_len, mem_ctx, UNMARSHALL); + prs_append_data(&ps, values[0]->bv_val, values[0]->bv_len); + ps.data_offset = 0; + + ret = sec_io_desc("sd", sd, &ps, 1); + } + + ldap_value_free_len(values); + return ret; +} + +/* + * in order to support usernames longer than 21 characters we need to + * use both the sAMAccountName and the userPrincipalName attributes + * It seems that not all users have the userPrincipalName attribute set + * + * @param ads connection to ads server + * @param mem_ctx TALLOC_CTX for allocating sid array + * @param msg Results of search + * @return the username + */ +char *ads_pull_username(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, void *msg) +{ + char *ret, *p; + + ret = ads_pull_string(ads, mem_ctx, msg, "userPrincipalName"); + if (ret && (p = strchr(ret, '@'))) { + *p = 0; + return ret; + } + return ads_pull_string(ads, mem_ctx, msg, "sAMAccountName"); +} + /** * find the update serial number - this is the core of the ldap cache @@ -1705,8 +1778,9 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads) ads->config.realm = strdup(p+2); ads->config.bind_path = ads_build_dn(ads->config.realm); - DEBUG(3,("got ldap server name %s@%s\n", - ads->config.ldap_server_name, ads->config.realm)); + DEBUG(3,("got ldap server name %s@%s, using bind path: %s\n", + ads->config.ldap_server_name, ads->config.realm, + ads->config.bind_path)); ads->config.current_time = ads_parse_time(timestr); diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index f7dd01084a..aa7d99a5f7 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -20,7 +20,7 @@ #include "includes.h" -#ifdef HAVE_ADS +#ifdef HAVE_LDAP /* perform a LDAP/SASL/SPNEGO/NTLMSSP bind (just how many layers can @@ -190,10 +190,12 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) } DEBUG(3,("got principal=%s\n", principal)); +#ifdef HAVE_KRB5 if (!(ads->auth.flags & ADS_AUTH_DISABLE_KERBEROS) && got_kerberos_mechanism && ads_kinit_password(ads) == 0) { return ads_sasl_spnego_krb5_bind(ads, principal); } +#endif /* lets do NTLMSSP ... this has the big advantage that we don't need to sync clocks, and we don't rely on special versions of the krb5 -- cgit From fa066fdde31d649929affa2d53fd52de1d5447fb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 3 Oct 2002 14:23:06 +0000 Subject: .NET likes both forms of servicePrincipalName in the machine account record (This used to be commit 8ff6d40d7fe4dc11e9ba194a55995c0926202df9) --- source3/libads/ldap.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 2133bf0719..809faa24b3 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1031,6 +1031,7 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, ADS_MODLIST mods; const char *objectClass[] = {"top", "person", "organizationalPerson", "user", "computer", NULL}; + char *servicePrincipalName[3] = {NULL, NULL, NULL}; if (!(ctx = talloc_init_named("machine_account"))) return ADS_ERROR(LDAP_NO_MEMORY); @@ -1048,6 +1049,12 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, } new_dn = talloc_asprintf(ctx, "cn=%s,%s,%s", hostname, ou_str, ads->config.bind_path); + servicePrincipalName[0] = talloc_asprintf(ctx, "HOST/%s", hostname); + servicePrincipalName[1] = talloc_asprintf(ctx, "HOST/%s.%s", + hostname, + ads->config.realm); + strlower(&servicePrincipalName[1][5]); + free(ou_str); if (!new_dn) goto done; @@ -1066,7 +1073,7 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, ads_mod_str(ctx, &mods, "sAMAccountName", samAccountName); ads_mod_strlist(ctx, &mods, "objectClass", objectClass); ads_mod_str(ctx, &mods, "userPrincipalName", host_upn); - ads_mod_str(ctx, &mods, "servicePrincipalName", host_spn); + ads_mod_strlist(ctx, &mods, "servicePrincipalName", servicePrincipalName); ads_mod_str(ctx, &mods, "dNSHostName", hostname); ads_mod_str(ctx, &mods, "userAccountControl", controlstr); ads_mod_str(ctx, &mods, "operatingSystem", "Samba"); -- cgit From 14f65fb89716959852849745c89c4108eb7bbe36 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 4 Oct 2002 07:41:56 +0000 Subject: support all permitted encoding types in tickets. This allows us to decode a type 23 ticket when the machine account is setup for non-DES tickets (This used to be commit 144d4429d7d91e8597263da6abc8041098f2a4c3) --- source3/libads/kerberos_verify.c | 44 ++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 15 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 22b58f47dd..52fd2e6862 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -38,7 +38,7 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, krb5_ticket *tkt = NULL; krb5_data salt; krb5_encrypt_block eblock; - int ret; + int ret, i; krb5_keyblock * key; krb5_principal host_princ; char *host_princ_s; @@ -46,6 +46,7 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, fstring myname; char *password_s; krb5_data password; + krb5_enctype *enctypes = NULL; if (!secrets_init()) { DEBUG(1,("secrets_init failed\n")); @@ -70,7 +71,6 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, ret = krb5_set_default_realm(context, ads->auth.realm); if (ret) { DEBUG(1,("krb5_set_default_realm failed (%s)\n", error_message(ret))); - ads_destroy(&ads); return NT_STATUS_LOGON_FAILURE; } @@ -102,30 +102,44 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, return NT_STATUS_NO_MEMORY; } - krb5_use_enctype(context, &eblock, ENCTYPE_DES_CBC_MD5); - - ret = krb5_string_to_key(context, &eblock, key, &password, &salt); - if (ret) { - DEBUG(1,("krb5_string_to_key failed (%s)\n", error_message(ret))); + if ((ret = krb5_get_permitted_enctypes(context, &enctypes))) { + DEBUG(1,("krb5_get_permitted_enctypes failed (%s)\n", + error_message(ret))); return NT_STATUS_LOGON_FAILURE; } - krb5_auth_con_setuseruserkey(context, auth_context, key); + /* we need to setup a auth context with each possible encoding type in turn */ + for (i=0;enctypes[i];i++) { + krb5_use_enctype(context, &eblock, enctypes[i]); - packet.length = ticket->length; - packet.data = (krb5_pointer)ticket->data; + ret = krb5_string_to_key(context, &eblock, key, &password, &salt); + if (ret) { + continue; + } -#if 0 - file_save("/tmp/ticket.dat", ticket->data, ticket->length); -#endif + krb5_auth_con_setuseruserkey(context, auth_context, key); + + packet.length = ticket->length; + packet.data = (krb5_pointer)ticket->data; - if ((ret = krb5_rd_req(context, &auth_context, &packet, - NULL, keytab, NULL, &tkt))) { + if (!(ret = krb5_rd_req(context, &auth_context, &packet, + NULL, keytab, NULL, &tkt))) { + krb5_free_ktypes(context, enctypes); + break; + } + } + + if (!enctypes[i]) { DEBUG(3,("krb5_rd_req with auth failed (%s)\n", error_message(ret))); return NT_STATUS_LOGON_FAILURE; } +#if 0 + file_save("/tmp/ticket.dat", ticket->data, ticket->length); +#endif + + if (tkt->enc_part2) { *auth_data = data_blob(tkt->enc_part2->authorization_data[0]->contents, tkt->enc_part2->authorization_data[0]->length); -- cgit From aadae4f84ab58d1b286dc997dc2dda3b0d4dc7ff Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 4 Oct 2002 07:47:42 +0000 Subject: only set UF_USE_DES_KEY_ONLY if we are using krb5 libraries that can't do type 23 (This used to be commit c0612272e8eea3d741854c0b4834bc687d787218) --- source3/libads/ldap.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 809faa24b3..d3c8b39e22 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1032,6 +1032,7 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, const char *objectClass[] = {"top", "person", "organizationalPerson", "user", "computer", NULL}; char *servicePrincipalName[3] = {NULL, NULL, NULL}; + unsigned acct_control; if (!(ctx = talloc_init_named("machine_account"))) return ADS_ERROR(LDAP_NO_MEMORY); @@ -1061,9 +1062,12 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, if (!(samAccountName = talloc_asprintf(ctx, "%s$", hostname))) goto done; - if (!(controlstr = talloc_asprintf(ctx, "%u", - UF_DONT_EXPIRE_PASSWD | UF_WORKSTATION_TRUST_ACCOUNT | - UF_TRUSTED_FOR_DELEGATION | UF_USE_DES_KEY_ONLY))) + + acct_control = UF_WORKSTATION_TRUST_ACCOUNT | UF_DONT_EXPIRE_PASSWD; +#ifndef ENCTYPE_ARCFOUR_HMAC + acct_control |= UF_USE_DES_KEY_ONLY; +#endif + if (!(controlstr = talloc_asprintf(ctx, "%u", acct_control))) goto done; if (!(mods = ads_init_mods(ctx))) -- cgit From e042a93cce2fdadfd88c93b813e10f0cc12f570e Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 18 Oct 2002 20:11:29 +0000 Subject: Format objectGUIDs on ads dumps. (This used to be commit 7eaf7e7115c75e682b1b9368c6f28c60429885e5) --- source3/libads/ldap.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index d3c8b39e22..2359dbd7ed 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1106,6 +1106,23 @@ static void dump_binary(const char *field, struct berval **values) } } +struct uuid { + uint32 i1; + uint16 i2; + uint16 i3; + uint8 s[8]; +}; + +static void dump_guid(const char *field, struct berval **values) +{ + int i; + GUID guid; + for (i=0; values[i]; i++) { + memcpy(guid.info, values[i]->bv_val, sizeof(guid.info)); + printf("%s: %s\n", field, uuid_string_static(guid)); + } +} + /* dump a sid result from ldap */ @@ -1172,7 +1189,7 @@ static BOOL ads_dump_field(char *field, void **values, void *data_area) BOOL string; void (*handler)(const char *, struct berval **); } handlers[] = { - {"objectGUID", False, dump_binary}, + {"objectGUID", False, dump_guid}, {"nTSecurityDescriptor", False, dump_sd}, {"dnsRecord", False, dump_binary}, {"objectSid", False, dump_sid}, -- cgit From 306e4cbead22e2bb12f699d0072eb8d5b1bc6733 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 23 Oct 2002 00:02:26 +0000 Subject: fixed a possible segv when dealing with a blank password (This used to be commit d5d0d0de50482ed16c594b1cc4cc113e2526a915) --- source3/libads/kerberos.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index b586d84226..bef2febaef 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -40,8 +40,12 @@ kerb_prompter(krb5_context ctx, void *data, memset(prompts[0].reply->data, 0, prompts[0].reply->length); if (prompts[0].reply->length > 0) { - strncpy(prompts[0].reply->data, data, prompts[0].reply->length-1); - prompts[0].reply->length = strlen(prompts[0].reply->data); + if (data) { + strncpy(prompts[0].reply->data, data, prompts[0].reply->length-1); + prompts[0].reply->length = strlen(prompts[0].reply->data); + } else { + prompts[0].reply->length = 0; + } } return 0; } -- cgit From 515e6a268e97a5d512535fd95138fa64ab46280e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 24 Oct 2002 01:05:30 +0000 Subject: Merge tridge's blank password fix from HEAD. Jeremy. (This used to be commit eadfd312ba92a780f655cf117c44b30457f007e8) --- source3/libads/kerberos.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index b586d84226..bef2febaef 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -40,8 +40,12 @@ kerb_prompter(krb5_context ctx, void *data, memset(prompts[0].reply->data, 0, prompts[0].reply->length); if (prompts[0].reply->length > 0) { - strncpy(prompts[0].reply->data, data, prompts[0].reply->length-1); - prompts[0].reply->length = strlen(prompts[0].reply->data); + if (data) { + strncpy(prompts[0].reply->data, data, prompts[0].reply->length-1); + prompts[0].reply->length = strlen(prompts[0].reply->data); + } else { + prompts[0].reply->length = 0; + } } return 0; } -- cgit From 4a7c48aaf0a189c7c6babb4f3745cfee0aa2b8e6 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Tue, 29 Oct 2002 14:47:11 +0000 Subject: Merge from HEAD: GUID formatting on ads dump Allow rc4-hmac when available .NET likes both forms of servicePrincipalName in machine account record (This used to be commit 89e3a3da5d5bc9e6aedeaea5a87553d72fcaac99) --- source3/libads/ldap.c | 38 +++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 2133bf0719..2359dbd7ed 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1031,6 +1031,8 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, ADS_MODLIST mods; const char *objectClass[] = {"top", "person", "organizationalPerson", "user", "computer", NULL}; + char *servicePrincipalName[3] = {NULL, NULL, NULL}; + unsigned acct_control; if (!(ctx = talloc_init_named("machine_account"))) return ADS_ERROR(LDAP_NO_MEMORY); @@ -1048,15 +1050,24 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, } new_dn = talloc_asprintf(ctx, "cn=%s,%s,%s", hostname, ou_str, ads->config.bind_path); + servicePrincipalName[0] = talloc_asprintf(ctx, "HOST/%s", hostname); + servicePrincipalName[1] = talloc_asprintf(ctx, "HOST/%s.%s", + hostname, + ads->config.realm); + strlower(&servicePrincipalName[1][5]); + free(ou_str); if (!new_dn) goto done; if (!(samAccountName = talloc_asprintf(ctx, "%s$", hostname))) goto done; - if (!(controlstr = talloc_asprintf(ctx, "%u", - UF_DONT_EXPIRE_PASSWD | UF_WORKSTATION_TRUST_ACCOUNT | - UF_TRUSTED_FOR_DELEGATION | UF_USE_DES_KEY_ONLY))) + + acct_control = UF_WORKSTATION_TRUST_ACCOUNT | UF_DONT_EXPIRE_PASSWD; +#ifndef ENCTYPE_ARCFOUR_HMAC + acct_control |= UF_USE_DES_KEY_ONLY; +#endif + if (!(controlstr = talloc_asprintf(ctx, "%u", acct_control))) goto done; if (!(mods = ads_init_mods(ctx))) @@ -1066,7 +1077,7 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, ads_mod_str(ctx, &mods, "sAMAccountName", samAccountName); ads_mod_strlist(ctx, &mods, "objectClass", objectClass); ads_mod_str(ctx, &mods, "userPrincipalName", host_upn); - ads_mod_str(ctx, &mods, "servicePrincipalName", host_spn); + ads_mod_strlist(ctx, &mods, "servicePrincipalName", servicePrincipalName); ads_mod_str(ctx, &mods, "dNSHostName", hostname); ads_mod_str(ctx, &mods, "userAccountControl", controlstr); ads_mod_str(ctx, &mods, "operatingSystem", "Samba"); @@ -1095,6 +1106,23 @@ static void dump_binary(const char *field, struct berval **values) } } +struct uuid { + uint32 i1; + uint16 i2; + uint16 i3; + uint8 s[8]; +}; + +static void dump_guid(const char *field, struct berval **values) +{ + int i; + GUID guid; + for (i=0; values[i]; i++) { + memcpy(guid.info, values[i]->bv_val, sizeof(guid.info)); + printf("%s: %s\n", field, uuid_string_static(guid)); + } +} + /* dump a sid result from ldap */ @@ -1161,7 +1189,7 @@ static BOOL ads_dump_field(char *field, void **values, void *data_area) BOOL string; void (*handler)(const char *, struct berval **); } handlers[] = { - {"objectGUID", False, dump_binary}, + {"objectGUID", False, dump_guid}, {"nTSecurityDescriptor", False, dump_sd}, {"dnsRecord", False, dump_binary}, {"objectSid", False, dump_sid}, -- cgit From 3b3c7914e2cd79ee5c6e76af14e386a590aed78e Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Wed, 30 Oct 2002 20:31:02 +0000 Subject: Take out gcb2gtype and gtype2gcb fns. They were using symbols not defined in 3.0 (new SAM in HEAD). Nobody was referencing these fns... (This used to be commit 386cc92dfa23b4e20172dff20fb14c2ad3172a58) --- source3/libads/ads_utils.c | 46 ---------------------------------------------- 1 file changed, 46 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_utils.c b/source3/libads/ads_utils.c index 626c177926..750940e336 100644 --- a/source3/libads/ads_utils.c +++ b/source3/libads/ads_utils.c @@ -88,52 +88,6 @@ uint32 ads_uf2atype(uint32 uf) return atype; } -/* -translated the GROUP_CTRL Flags to GroupType (groupType) -*/ -uint32 ads_gcb2gtype(uint16 gcb) -{ - uint32 gtype = 0x00000000; - - if (gcb & GCB_ALIAS_GROUP) gtype |= GTYPE_SECURITY_BUILTIN_LOCAL_GROUP; - else if(gcb & GCB_LOCAL_GROUP) gtype |= GTYPE_SECURITY_DOMAIN_LOCAL_GROUP; - if (gcb & GCB_GLOBAL_GROUP) gtype |= GTYPE_SECURITY_GLOBAL_GROUP; - - return gtype; -} - -/* -translated the GroupType (groupType) to GROUP_CTRL Flags -*/ -uint16 ads_gtype2gcb(uint32 gtype) -{ - uint16 gcb = 0x0000; - - switch(gtype) { - case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP: - gcb = GCB_ALIAS_GROUP; - break; - case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP: - gcb = GCB_LOCAL_GROUP; - break; - case GTYPE_SECURITY_GLOBAL_GROUP: - gcb = GCB_GLOBAL_GROUP; - break; - - case GTYPE_DISTRIBUTION_GLOBAL_GROUP: - gcb = GCB_GLOBAL_GROUP; - break; - case GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP: - gcb = GCB_LOCAL_GROUP; - break; - case GTYPE_DISTRIBUTION_UNIVERSAL_GROUP: - gcb = GCB_GLOBAL_GROUP; - break; - } - - return gcb; -} - /* get the accountType from the groupType */ -- cgit From 69a2042dc607da52eca85f93e115339b0a859b12 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Thu, 31 Oct 2002 19:20:33 +0000 Subject: Re-enable use of existing kerberos tickets. (This used to be commit 6ec5dce69834e72e458a8acff7d1790cbdd46d67) --- source3/libads/sasl.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index aa7d99a5f7..dacf8f7da8 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -192,8 +192,12 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) #ifdef HAVE_KRB5 if (!(ads->auth.flags & ADS_AUTH_DISABLE_KERBEROS) && - got_kerberos_mechanism && ads_kinit_password(ads) == 0) { - return ads_sasl_spnego_krb5_bind(ads, principal); + got_kerberos_mechanism) { + status = ads_sasl_spnego_krb5_bind(ads, principal); + if (ADS_ERR_OK(status)) + return status; + if (ads_kinit_password(ads) == 0) + return ads_sasl_spnego_krb5_bind(ads, principal); } #endif -- cgit From ea24bb2da8f643e043dc3af3ed3f16388878b57b Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 6 Nov 2002 01:29:07 +0000 Subject: Merge of get_dc_list() api change. This was slightly more intrusive than the version in APPLIANCE so watch out for boogs. (This used to be commit 1e054e3db654801fbb5580211529cdfdea9ed686) --- source3/libads/ldap.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 2359dbd7ed..a59b78bf13 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -180,7 +180,7 @@ static BOOL ads_try_dns(ADS_STRUCT *ads) /* try connecting to a ldap server via netbios */ static BOOL ads_try_netbios(ADS_STRUCT *ads) { - struct in_addr *ip_list; + struct in_addr *ip_list, pdc_ip; int count; int i; char *workgroup = ads->server.workgroup; @@ -192,20 +192,15 @@ static BOOL ads_try_netbios(ADS_STRUCT *ads) DEBUG(6,("ads_try_netbios: looking for workgroup '%s'\n", workgroup)); /* try the PDC first */ - if (get_dc_list(True, workgroup, &ip_list, &count)) { - for (i=0;i Date: Wed, 6 Nov 2002 05:14:15 +0000 Subject: Merge of get_dc_list() api change from HEAD. (This used to be commit 6ba7847ce2756fde94e530fd0bf2a055f3e27373) --- source3/libads/ldap.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 2359dbd7ed..a59b78bf13 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -180,7 +180,7 @@ static BOOL ads_try_dns(ADS_STRUCT *ads) /* try connecting to a ldap server via netbios */ static BOOL ads_try_netbios(ADS_STRUCT *ads) { - struct in_addr *ip_list; + struct in_addr *ip_list, pdc_ip; int count; int i; char *workgroup = ads->server.workgroup; @@ -192,20 +192,15 @@ static BOOL ads_try_netbios(ADS_STRUCT *ads) DEBUG(6,("ads_try_netbios: looking for workgroup '%s'\n", workgroup)); /* try the PDC first */ - if (get_dc_list(True, workgroup, &ip_list, &count)) { - for (i=0;i Date: Sun, 10 Nov 2002 00:35:04 +0000 Subject: make sure that if kerberos fails we can fall back on NTLMSSP for SASL (This used to be commit 69dba08c40c9739137b4f01d38be5228edc6dd6e) --- source3/libads/sasl.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index dacf8f7da8..16ad397d0e 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -196,8 +196,11 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) status = ads_sasl_spnego_krb5_bind(ads, principal); if (ADS_ERR_OK(status)) return status; - if (ads_kinit_password(ads) == 0) - return ads_sasl_spnego_krb5_bind(ads, principal); + if (ads_kinit_password(ads) == 0) { + status = ads_sasl_spnego_krb5_bind(ads, principal); + } + if (ADS_ERR_OK(status)) + return status; } #endif -- cgit From f48a8615d67c2ccba3a0b65877402b24493da58e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 10 Nov 2002 03:07:19 +0000 Subject: After the lord mayors parade...... Janitor for tridge :-). Jeremy. (This used to be commit 76cdfbd5107fff0c38f5fc339f1c27b33fec3a91) --- source3/libads/sasl.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index aa7d99a5f7..16ad397d0e 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -192,8 +192,15 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) #ifdef HAVE_KRB5 if (!(ads->auth.flags & ADS_AUTH_DISABLE_KERBEROS) && - got_kerberos_mechanism && ads_kinit_password(ads) == 0) { - return ads_sasl_spnego_krb5_bind(ads, principal); + got_kerberos_mechanism) { + status = ads_sasl_spnego_krb5_bind(ads, principal); + if (ADS_ERR_OK(status)) + return status; + if (ads_kinit_password(ads) == 0) { + status = ads_sasl_spnego_krb5_bind(ads, principal); + } + if (ADS_ERR_OK(status)) + return status; } #endif -- cgit From 250c9801197ea1c949bd94c1c891f81ab118b130 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 12 Nov 2002 23:15:52 +0000 Subject: Removed global_myworkgroup, global_myname, global_myscope. Added liberal dashes of const. This is a rather large check-in, some things may break. It does compile though :-). Jeremy. (This used to be commit 82b8f749a36b42e22186297482aad2abb04fab8a) --- source3/libads/kerberos_verify.c | 3 +-- source3/libads/ldap.c | 38 ++++++++++++++++++++------------------ source3/libads/ldap_printer.c | 9 ++++----- source3/libads/sasl.c | 3 +-- 4 files changed, 26 insertions(+), 27 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 52fd2e6862..03917466c6 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -42,7 +42,6 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, krb5_keyblock * key; krb5_principal host_princ; char *host_princ_s; - extern pstring global_myname; fstring myname; char *password_s; krb5_data password; @@ -83,7 +82,7 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, return NT_STATUS_LOGON_FAILURE; } - fstrcpy(myname, global_myname); + fstrcpy(myname, global_myname()); strlower(myname); asprintf(&host_princ_s, "HOST/%s@%s", myname, lp_realm()); ret = krb5_parse_name(context, host_princ_s, &host_princ); diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index a59b78bf13..d5cd56001b 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -105,26 +105,28 @@ static int ldap_ip_compare(struct ldap_ip *ip1, struct ldap_ip *ip2) /* try connecting to a ldap server via DNS */ static BOOL ads_try_dns(ADS_STRUCT *ads) { - char *realm, *ptr; + const char *c_realm; + const char *ptr; + char *realm; char *list = NULL; pstring tok; struct ldap_ip *ip_list; int count, i=0; - realm = ads->server.realm; - if (!realm || !*realm) { - realm = lp_realm(); + c_realm = ads->server.realm; + if (!c_realm || !*c_realm) { + c_realm = lp_realm(); } - if (!realm || !*realm) { - realm = ads->server.workgroup; + if (!c_realm || !*c_realm) { + c_realm = ads->server.workgroup; } - if (!realm || !*realm) { - realm = lp_workgroup(); + if (!c_realm || !*c_realm) { + c_realm = lp_workgroup(); } - if (!realm) { + if (!c_realm) { return False; } - realm = smb_xstrdup(realm); + realm = smb_xstrdup(c_realm); DEBUG(6,("ads_try_dns: looking for realm '%s'\n", realm)); if (ldap_domain2hostlist(realm, &list) != LDAP_SUCCESS) { @@ -183,7 +185,7 @@ static BOOL ads_try_netbios(ADS_STRUCT *ads) struct in_addr *ip_list, pdc_ip; int count; int i; - char *workgroup = ads->server.workgroup; + const char *workgroup = ads->server.workgroup; if (!workgroup) { workgroup = lp_workgroup(); @@ -273,9 +275,8 @@ got_connection: if (!ads->auth.user_name) { /* by default use the machine account */ - extern pstring global_myname; fstring myname; - fstrcpy(myname, global_myname); + fstrcpy(myname, global_myname()); strlower(myname); asprintf(&ads->auth.user_name, "HOST/%s", myname); } @@ -435,8 +436,7 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, else { /* This would be the utf8-encoded version...*/ /* if (!(search_attrs = ads_push_strvals(ctx, attrs))) */ - if (!(str_list_copy(&search_attrs, attrs))) - { + if (!(str_list_copy(&search_attrs, attrs))) { rc = LDAP_NO_MEMORY; goto done; } @@ -1026,7 +1026,8 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, ADS_MODLIST mods; const char *objectClass[] = {"top", "person", "organizationalPerson", "user", "computer", NULL}; - char *servicePrincipalName[3] = {NULL, NULL, NULL}; + const char *servicePrincipalName[3] = {NULL, NULL, NULL}; + char *psp; unsigned acct_control; if (!(ctx = talloc_init_named("machine_account"))) @@ -1046,10 +1047,11 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, new_dn = talloc_asprintf(ctx, "cn=%s,%s,%s", hostname, ou_str, ads->config.bind_path); servicePrincipalName[0] = talloc_asprintf(ctx, "HOST/%s", hostname); - servicePrincipalName[1] = talloc_asprintf(ctx, "HOST/%s.%s", + psp = talloc_asprintf(ctx, "HOST/%s.%s", hostname, ads->config.realm); - strlower(&servicePrincipalName[1][5]); + strlower(&psp[5]); + servicePrincipalName[1] = psp; free(ou_str); if (!new_dn) diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index 66984477b8..0185bf7811 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -28,7 +28,7 @@ results can be used. It should be freed using ads_msgfree. */ ADS_STATUS ads_find_printer_on_server(ADS_STRUCT *ads, void **res, - const char *printer, char *servername) + const char *printer, const char *servername) { ADS_STATUS status; char *srv_dn, **srv_cn, *exp; @@ -77,7 +77,7 @@ ADS_STATUS ads_mod_printer_entry(ADS_STRUCT *ads, char *prt_dn, ads_mod_str(ctx, &mods, "versionNumber", prt->versionNumber); /* now the optional ones */ - ads_mod_strlist(ctx, &mods, "description", prt->description); + ads_mod_strlist(ctx, &mods, "description", (const char **)prt->description); ads_mod_str(ctx, &mods, "assetNumber",prt->assetNumber); ads_mod_str(ctx, &mods, "bytesPerMinute",prt->bytesPerMinute); ads_mod_str(ctx, &mods, "defaultPriority",prt->defaultPriority); @@ -93,10 +93,10 @@ ADS_STATUS ads_mod_printer_entry(ADS_STRUCT *ads, char *prt_dn, prt->operatingSystemVersion); ads_mod_str(ctx, &mods, "physicalLocationObject", prt->physicalLocationObject); - ads_mod_strlist(ctx, &mods, "portName", prt->portName); + ads_mod_strlist(ctx, &mods, "portName", (const char **)prt->portName); ads_mod_str(ctx, &mods, "printStartTime", prt->printStartTime); ads_mod_str(ctx, &mods, "printEndTime", prt->printEndTime); - ads_mod_strlist(ctx, &mods, "printBinNames", prt->printBinNames); + ads_mod_strlist(ctx, &mods, "printBinNames", (const char **)prt->printBinNames); /*... and many others */ /* do the ldap modify */ @@ -107,7 +107,6 @@ ADS_STATUS ads_mod_printer_entry(ADS_STRUCT *ads, char *prt_dn, return status; } - /* add a printer to the directory diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 16ad397d0e..7aa77bf2a2 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -36,7 +36,6 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) uint32 neg_flags; struct berval cred, *scred; ADS_STATUS status; - extern pstring global_myname; int rc; if (!ads->auth.password) { @@ -97,7 +96,7 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) nthash, 24, lp_workgroup(), ads->auth.user_name, - global_myname, + global_myname(), sess_key, 16, neg_flags); -- cgit From 2f194322d419350f35a48dff750066894d68eccf Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 12 Nov 2002 23:20:50 +0000 Subject: Removed global_myworkgroup, global_myname, global_myscope. Added liberal dashes of const. This is a rather large check-in, some things may break. It does compile though :-). Jeremy. (This used to be commit f755711df8f74f9b8e8c1a2b0d07d02a931eeb89) --- source3/libads/kerberos_verify.c | 3 +-- source3/libads/ldap.c | 38 ++++++++++++++++++++------------------ source3/libads/ldap_printer.c | 9 ++++----- source3/libads/sasl.c | 3 +-- 4 files changed, 26 insertions(+), 27 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 22b58f47dd..f761467d6f 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -42,7 +42,6 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, krb5_keyblock * key; krb5_principal host_princ; char *host_princ_s; - extern pstring global_myname; fstring myname; char *password_s; krb5_data password; @@ -83,7 +82,7 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, return NT_STATUS_LOGON_FAILURE; } - fstrcpy(myname, global_myname); + fstrcpy(myname, global_myname()); strlower(myname); asprintf(&host_princ_s, "HOST/%s@%s", myname, lp_realm()); ret = krb5_parse_name(context, host_princ_s, &host_princ); diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index a59b78bf13..d5cd56001b 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -105,26 +105,28 @@ static int ldap_ip_compare(struct ldap_ip *ip1, struct ldap_ip *ip2) /* try connecting to a ldap server via DNS */ static BOOL ads_try_dns(ADS_STRUCT *ads) { - char *realm, *ptr; + const char *c_realm; + const char *ptr; + char *realm; char *list = NULL; pstring tok; struct ldap_ip *ip_list; int count, i=0; - realm = ads->server.realm; - if (!realm || !*realm) { - realm = lp_realm(); + c_realm = ads->server.realm; + if (!c_realm || !*c_realm) { + c_realm = lp_realm(); } - if (!realm || !*realm) { - realm = ads->server.workgroup; + if (!c_realm || !*c_realm) { + c_realm = ads->server.workgroup; } - if (!realm || !*realm) { - realm = lp_workgroup(); + if (!c_realm || !*c_realm) { + c_realm = lp_workgroup(); } - if (!realm) { + if (!c_realm) { return False; } - realm = smb_xstrdup(realm); + realm = smb_xstrdup(c_realm); DEBUG(6,("ads_try_dns: looking for realm '%s'\n", realm)); if (ldap_domain2hostlist(realm, &list) != LDAP_SUCCESS) { @@ -183,7 +185,7 @@ static BOOL ads_try_netbios(ADS_STRUCT *ads) struct in_addr *ip_list, pdc_ip; int count; int i; - char *workgroup = ads->server.workgroup; + const char *workgroup = ads->server.workgroup; if (!workgroup) { workgroup = lp_workgroup(); @@ -273,9 +275,8 @@ got_connection: if (!ads->auth.user_name) { /* by default use the machine account */ - extern pstring global_myname; fstring myname; - fstrcpy(myname, global_myname); + fstrcpy(myname, global_myname()); strlower(myname); asprintf(&ads->auth.user_name, "HOST/%s", myname); } @@ -435,8 +436,7 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, else { /* This would be the utf8-encoded version...*/ /* if (!(search_attrs = ads_push_strvals(ctx, attrs))) */ - if (!(str_list_copy(&search_attrs, attrs))) - { + if (!(str_list_copy(&search_attrs, attrs))) { rc = LDAP_NO_MEMORY; goto done; } @@ -1026,7 +1026,8 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, ADS_MODLIST mods; const char *objectClass[] = {"top", "person", "organizationalPerson", "user", "computer", NULL}; - char *servicePrincipalName[3] = {NULL, NULL, NULL}; + const char *servicePrincipalName[3] = {NULL, NULL, NULL}; + char *psp; unsigned acct_control; if (!(ctx = talloc_init_named("machine_account"))) @@ -1046,10 +1047,11 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, new_dn = talloc_asprintf(ctx, "cn=%s,%s,%s", hostname, ou_str, ads->config.bind_path); servicePrincipalName[0] = talloc_asprintf(ctx, "HOST/%s", hostname); - servicePrincipalName[1] = talloc_asprintf(ctx, "HOST/%s.%s", + psp = talloc_asprintf(ctx, "HOST/%s.%s", hostname, ads->config.realm); - strlower(&servicePrincipalName[1][5]); + strlower(&psp[5]); + servicePrincipalName[1] = psp; free(ou_str); if (!new_dn) diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index 66984477b8..0185bf7811 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -28,7 +28,7 @@ results can be used. It should be freed using ads_msgfree. */ ADS_STATUS ads_find_printer_on_server(ADS_STRUCT *ads, void **res, - const char *printer, char *servername) + const char *printer, const char *servername) { ADS_STATUS status; char *srv_dn, **srv_cn, *exp; @@ -77,7 +77,7 @@ ADS_STATUS ads_mod_printer_entry(ADS_STRUCT *ads, char *prt_dn, ads_mod_str(ctx, &mods, "versionNumber", prt->versionNumber); /* now the optional ones */ - ads_mod_strlist(ctx, &mods, "description", prt->description); + ads_mod_strlist(ctx, &mods, "description", (const char **)prt->description); ads_mod_str(ctx, &mods, "assetNumber",prt->assetNumber); ads_mod_str(ctx, &mods, "bytesPerMinute",prt->bytesPerMinute); ads_mod_str(ctx, &mods, "defaultPriority",prt->defaultPriority); @@ -93,10 +93,10 @@ ADS_STATUS ads_mod_printer_entry(ADS_STRUCT *ads, char *prt_dn, prt->operatingSystemVersion); ads_mod_str(ctx, &mods, "physicalLocationObject", prt->physicalLocationObject); - ads_mod_strlist(ctx, &mods, "portName", prt->portName); + ads_mod_strlist(ctx, &mods, "portName", (const char **)prt->portName); ads_mod_str(ctx, &mods, "printStartTime", prt->printStartTime); ads_mod_str(ctx, &mods, "printEndTime", prt->printEndTime); - ads_mod_strlist(ctx, &mods, "printBinNames", prt->printBinNames); + ads_mod_strlist(ctx, &mods, "printBinNames", (const char **)prt->printBinNames); /*... and many others */ /* do the ldap modify */ @@ -107,7 +107,6 @@ ADS_STATUS ads_mod_printer_entry(ADS_STRUCT *ads, char *prt_dn, return status; } - /* add a printer to the directory diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 16ad397d0e..7aa77bf2a2 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -36,7 +36,6 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) uint32 neg_flags; struct berval cred, *scred; ADS_STATUS status; - extern pstring global_myname; int rc; if (!ads->auth.password) { @@ -97,7 +96,7 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) nthash, 24, lp_workgroup(), ads->auth.user_name, - global_myname, + global_myname(), sess_key, 16, neg_flags); -- cgit From 77d0ff6357c74beccf9e438a9980df1b4b19dce4 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 15 Nov 2002 21:25:40 +0000 Subject: Include the hostname we are trying to match with $@, to allow easier debugging. (This used to be commit f5d8afc626b8f7792aa7dd7fa7082f55725b539c) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index d5cd56001b..60427323b0 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1790,8 +1790,8 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads) p = strchr(ads->config.ldap_server_name, '$'); if (!p || p[1] != '@') { talloc_destroy(ctx); + DEBUG(1, ("ads_server_info: returned ldap server name (%s) does not contain '$@' so was deemed invalid\n", ads->config.ldap_server_name)); SAFE_FREE(ads->config.ldap_server_name); - DEBUG(1, ("ads_server_info: returned ldap server name did not contain '$@' so was deemed invalid\n")); return ADS_ERROR(LDAP_DECODING_ERROR); } -- cgit From c64d762997c80bd9ad2d47d1799cf9ec870d455a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 15 Nov 2002 21:43:57 +0000 Subject: Updates from HEAD: - const for PACKS() in lanman.c - change auth to 'account before password' - add help to net rpc {vampire,samsync} - configure updates for sun workshop cc - become_root() around pdb_ calls in auth_util for guest login. Andrew Bartlett (This used to be commit 43e90eb6e331d478013a9c038292f245edc51bd0) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index d5cd56001b..60427323b0 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1790,8 +1790,8 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads) p = strchr(ads->config.ldap_server_name, '$'); if (!p || p[1] != '@') { talloc_destroy(ctx); + DEBUG(1, ("ads_server_info: returned ldap server name (%s) does not contain '$@' so was deemed invalid\n", ads->config.ldap_server_name)); SAFE_FREE(ads->config.ldap_server_name); - DEBUG(1, ("ads_server_info: returned ldap server name did not contain '$@' so was deemed invalid\n")); return ADS_ERROR(LDAP_DECODING_ERROR); } -- cgit From bbd3e4b40a511bff8656e11fa993dce26e02aa0f Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Mon, 18 Nov 2002 19:50:36 +0000 Subject: Next step of printer publishing. net ads printer publish [servername] Will retreive the DsSpooler and DsDriver info by rpc for a remote server then publish it. Next comes doing it within smbd (This used to be commit 64951938cc5666a757683cbe9bee3a2c20a05323) --- source3/libads/ldap_printer.c | 348 +++++++++++++++++++++++++++++------------- 1 file changed, 242 insertions(+), 106 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index 0185bf7811..4a983b20e3 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -54,142 +54,278 @@ ADS_STATUS ads_find_printer_on_server(ADS_STRUCT *ads, void **res, } /* - modify an entire printer entry in the directory + modify a printer entry in the directory */ ADS_STATUS ads_mod_printer_entry(ADS_STRUCT *ads, char *prt_dn, - const ADS_PRINTER_ENTRY *prt) + TALLOC_CTX *ctx, const ADS_MODLIST *mods) { - ADS_MODLIST mods; - ADS_STATUS status; - TALLOC_CTX *ctx; - - if (!(ctx = talloc_init_named("mod_printer_entry"))) - return ADS_ERROR(LDAP_NO_MEMORY); - - /* allocate the list */ - mods = ads_init_mods(ctx); - - /* add the attributes to the list - required ones first */ - ads_mod_str(ctx, &mods, "printerName", prt->printerName); - ads_mod_str(ctx, &mods, "serverName", prt->serverName); - ads_mod_str(ctx, &mods, "shortServerName", prt->shortServerName); - ads_mod_str(ctx, &mods, "uNCName", prt->uNCName); - ads_mod_str(ctx, &mods, "versionNumber", prt->versionNumber); - - /* now the optional ones */ - ads_mod_strlist(ctx, &mods, "description", (const char **)prt->description); - ads_mod_str(ctx, &mods, "assetNumber",prt->assetNumber); - ads_mod_str(ctx, &mods, "bytesPerMinute",prt->bytesPerMinute); - ads_mod_str(ctx, &mods, "defaultPriority",prt->defaultPriority); - ads_mod_str(ctx, &mods, "driverName", prt->driverName); - ads_mod_str(ctx, &mods, "driverVersion",prt->driverVersion); - ads_mod_str(ctx, &mods, "location", prt->location); - ads_mod_str(ctx, &mods, "operatingSystem",prt->operatingSystem); - ads_mod_str(ctx, &mods, "operatingSystemHotfix", - prt->operatingSystemHotfix); - ads_mod_str(ctx, &mods, "operatingSystemServicePack", - prt->operatingSystemServicePack); - ads_mod_str(ctx, &mods, "operatingSystemVersion", - prt->operatingSystemVersion); - ads_mod_str(ctx, &mods, "physicalLocationObject", - prt->physicalLocationObject); - ads_mod_strlist(ctx, &mods, "portName", (const char **)prt->portName); - ads_mod_str(ctx, &mods, "printStartTime", prt->printStartTime); - ads_mod_str(ctx, &mods, "printEndTime", prt->printEndTime); - ads_mod_strlist(ctx, &mods, "printBinNames", (const char **)prt->printBinNames); - /*... and many others */ - - /* do the ldap modify */ - status = ads_gen_mod(ads, prt_dn, mods); - - /* free mod list, mods, and values */ - talloc_destroy(ctx); - - return status; + return ads_gen_mod(ads, prt_dn, *mods); } /* add a printer to the directory */ -static ADS_STATUS ads_add_printer_entry(ADS_STRUCT *ads, char *prt_dn, - const ADS_PRINTER_ENTRY *prt) +ADS_STATUS ads_add_printer_entry(ADS_STRUCT *ads, char *prt_dn, + TALLOC_CTX *ctx, ADS_MODLIST *mods) { - ADS_STATUS status; - TALLOC_CTX *ctx; - ADS_MODLIST mods; + ads_mod_str(ctx, mods, "objectClass", "printQueue"); + return ads_gen_add(ads, prt_dn, *mods); +} - if (!(ctx = talloc_init_named("add_printer_entry"))) - return ADS_ERROR(LDAP_NO_MEMORY); +/* + map a REG_SZ to an ldap mod +*/ +static BOOL map_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods, + const REGISTRY_VALUE *value) +{ + char *str_value = NULL; - if (!(mods = ads_init_mods(ctx))) - return ADS_ERROR(LDAP_NO_MEMORY); + if (value->type != REG_SZ) + return False; - /* These are the fields a printQueue must contain */ - ads_mod_str(ctx, &mods, "uNCName", prt->uNCName); - ads_mod_str(ctx, &mods, "versionNumber", prt->versionNumber); - ads_mod_str(ctx, &mods, "serverName", prt->serverName); - ads_mod_str(ctx, &mods, "shortServerName", prt->shortServerName); - ads_mod_str(ctx, &mods, "printerName", prt->printerName); - ads_mod_str(ctx, &mods, "objectClass", "printQueue"); + if (value->size && *((smb_ucs2_t *) value->data_p)) { + pull_ucs2_talloc(ctx, (void **) &str_value, + (const smb_ucs2_t *) value->data_p); + return ADS_ERR_OK(ads_mod_str(ctx, mods, value->valuename, + str_value)); + } + return True; + +} +/* + map a REG_DWORD to an ldap mod +*/ +static BOOL map_dword(TALLOC_CTX *ctx, ADS_MODLIST *mods, + const REGISTRY_VALUE *value) +{ + char *str_value = NULL; - status = ads_gen_add(ads, prt_dn, mods); + if (value->type != REG_DWORD) + return False; + str_value = talloc_asprintf(ctx, "%d", *((uint32 *) value->data_p)); + return ADS_ERR_OK(ads_mod_str(ctx, mods, value->valuename, str_value)); +} - talloc_destroy(ctx); +/* + map a boolean REG_BINARY to an ldap mod +*/ +static BOOL map_bool(TALLOC_CTX *ctx, ADS_MODLIST *mods, + const REGISTRY_VALUE *value) +{ + char *str_value; - return status; + if ((value->type != REG_BINARY) || (value->size != 1)) + return False; + str_value = talloc_asprintf(ctx, "%s", + *(value->data_p) ? "TRUE" : "FALSE"); + return ADS_ERR_OK(ads_mod_str(ctx, mods, value->valuename, str_value)); } /* - publish a printer in the ADS + map a REG_MULTI_SZ to an ldap mod */ - -ADS_STATUS ads_add_printer(ADS_STRUCT *ads, const ADS_PRINTER_ENTRY *prt) +static BOOL map_multi_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods, + const REGISTRY_VALUE *value) { - ADS_STATUS status; - void *res; - char *host_dn, *prt_dn; - const char *attrs[] = {"*", "nTSecurityDescriptor", NULL}; + char **str_values = NULL; + smb_ucs2_t *cur_str = (smb_ucs2_t *) value->data_p; + uint32 size = 0, num_vals = 0, i=0; + + if (value->type != REG_MULTI_SZ) + return False; + + while(cur_str && *cur_str && (size < value->size)) { + size += 2 * (strlen_w(cur_str) + 1); + cur_str += strlen_w(cur_str) + 1; + num_vals++; + }; + + if (num_vals) { + str_values = talloc(ctx, + (num_vals + 1) * sizeof(smb_ucs2_t *)); + memset(str_values, '\0', + (num_vals + 1) * sizeof(smb_ucs2_t *)); + + cur_str = (smb_ucs2_t *) value->data_p; + for (i=0; i < num_vals; i++) + cur_str += pull_ucs2_talloc(ctx, + (void **) &str_values[i], + cur_str); + + return ADS_ERR_OK(ads_mod_strlist(ctx, mods, value->valuename, + (const char **) str_values)); + } + return True; +} - status = ads_find_machine_acct(ads, (void **)&res, - prt->shortServerName); - if (!ADS_ERR_OK(status)) { - DEBUG(1, ("ads_add_printer: cannot find host %s in ads\n", - prt->shortServerName)); - return status; - } - host_dn = ads_get_dn(ads, res); - ads_msgfree(ads, res); - - ads_find_printer_on_server(ads, &res, prt->printerName, - prt->shortServerName); - - if (ADS_ERR_OK(status) && ads_count_replies(ads, res)) { - DEBUG(1, ("ads_add_printer: printer %s already exists\n", - prt->printerName)); - /* nothing to do, just free results */ - ads_msgfree(ads, res); - } else { - ads_msgfree(ads, res); - status = ads_add_printer_entry(ads, prt_dn, prt); - if (!ADS_ERR_OK(status)) { - DEBUG(0, ("ads_add_printer: ads_add_printer_entry failed\n")); - return status; +struct valmap_to_ads { + char *valname; + BOOL (*fn)(TALLOC_CTX *, ADS_MODLIST *, const REGISTRY_VALUE *); +}; + +/* + map a REG_SZ to an ldap mod +*/ +static void map_regval_to_ads(TALLOC_CTX *ctx, ADS_MODLIST *mods, + REGISTRY_VALUE *value) +{ + struct valmap_to_ads map[] = { + {"assetNumber", map_sz}, + {"bytesPerMinute", map_dword}, + {"defaultPriority", map_dword}, + {"driverName", map_sz}, + {"driverVersion", map_dword}, + {"flags", map_dword}, + {"location", map_sz}, + {"operatingSystem", map_sz}, + {"operatingSystemHotfix", map_sz}, + {"operatingSystemServicePack", map_sz}, + {"operatingSystemVersion", map_sz}, + {"portName", map_multi_sz}, + {"printAttributes", map_dword}, + {"printBinNames", map_multi_sz}, + {"printCollate", map_bool}, + {"printColor", map_bool}, + {"printDuplexSupported", map_bool}, + {"printEndTime", map_dword}, + {"printFormName", map_sz}, + {"printKeepPrintedJobs", map_bool}, + {"printLanguage", map_multi_sz}, + {"printMACAddress", map_sz}, + {"printMaxCopies", map_sz}, + {"printMaxResolutionSupported", map_dword}, + {"printMaxXExtent", map_dword}, + {"printMaxYExtent", map_dword}, + {"printMediaReady", map_multi_sz}, + {"printMediaSupported", map_multi_sz}, + {"printMemory", map_dword}, + {"printMinXExtent", map_dword}, + {"printMinYExtent", map_dword}, + {"printNetworkAddress", map_sz}, + {"printNotify", map_sz}, + {"printNumberUp", map_dword}, + {"printOrientationsSupported", map_multi_sz}, + {"printOwner", map_sz}, + {"printPagesPerMinute", map_dword}, + {"printRate", map_dword}, + {"printRateUnit", map_sz}, + {"printSeparatorFile", map_sz}, + {"printShareName", map_sz}, + {"printSpooling", map_sz}, + {"printStaplingSupported", map_bool}, + {"printStartTime", map_dword}, + {"printStatus", map_sz}, + {"priority", map_dword}, + {"serverName", map_sz}, + {"shortServerName", map_sz}, + {"uNCName", map_sz}, + {"url", map_sz}, + {"versionNumber", map_dword}, + {NULL, NULL} + }; + int i; + + for (i=0; map[i].valname; i++) { + if (StrCaseCmp(map[i].valname, value->valuename) == 0) { + if (!map[i].fn(ctx, mods, value)) { + DEBUG(5, ("Add of value %s to modlist failed\n", value->valuename)); + } else { + DEBUG(7, ("Mapped value %s\n", value->valuename)); + } + } } +} + - status = ads_search_dn(ads, &res, prt_dn, attrs); +WERROR get_remote_printer_publishing_data(struct cli_state *cli, + TALLOC_CTX *mem_ctx, + ADS_MODLIST *mods, + char *printer) +{ + WERROR result; + char *printername, *servername; + REGVAL_CTR dsdriver_ctr, dsspooler_ctr; + uint32 needed, i; + POLICY_HND pol; + + asprintf(&servername, "\\\\%s", cli->desthost); + asprintf(&printername, "%s\\%s", servername, printer); + if (!servername || !printername) { + DEBUG(3, ("Insufficient memory\n")); + return WERR_NOMEM; + } + + result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, + "", MAXIMUM_ALLOWED_ACCESS, + servername, cli->user_name, &pol); + if (!W_ERROR_IS_OK(result)) { + DEBUG(3, ("Unable to open printer %s, error is %s.\n", + printername, dos_errstr(result))); + return result; + } + + result = cli_spoolss_enumprinterdataex(cli, mem_ctx, 0, &needed, + &pol, "DsDriver", NULL); + + if (W_ERROR_V(result) == ERRmoredata) + result = cli_spoolss_enumprinterdataex(cli, mem_ctx, needed, + NULL, &pol, "DsDriver", + &dsdriver_ctr); + + if (!W_ERROR_IS_OK(result)) { + DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n", + printername, dos_errstr(result))); + cli_spoolss_close_printer(cli, mem_ctx, &pol); + return result; + } - if (ADS_ERR_OK(status) && ads_count_replies(ads, res)) { - /* need to retrieve GUID from results - prt->GUID */ - status = ads_mod_printer_entry(ads, prt_dn, prt); + /* Have the data we need now, so start building */ + + for (i=0; i < dsdriver_ctr.num_values; i++) + map_regval_to_ads(mem_ctx, mods, dsdriver_ctr.values[i]); + + result = cli_spoolss_enumprinterdataex(cli, mem_ctx, 0, &needed, + &pol, "DsSpooler", NULL); + + if (W_ERROR_V(result) == ERRmoredata) + result = cli_spoolss_enumprinterdataex(cli, mem_ctx, needed, + NULL, &pol, "DsSpooler", + &dsspooler_ctr); + + if (!W_ERROR_IS_OK(result)) { + DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n", + printername, dos_errstr(result))); + regval_ctr_destroy(&dsdriver_ctr); + cli_spoolss_close_printer(cli, mem_ctx, &pol); + return result; } + for (i=0; i < dsspooler_ctr.num_values; i++) + map_regval_to_ads(mem_ctx, mods, dsspooler_ctr.values[i]); + + ads_mod_str(mem_ctx, mods, "printerName", printername); - ads_msgfree(ads, res); + regval_ctr_destroy(&dsdriver_ctr); + regval_ctr_destroy(&dsspooler_ctr); + cli_spoolss_close_printer(cli, mem_ctx, &pol); + return result; +} - return status; +BOOL get_local_printer_publishing_data(TALLOC_CTX *mem_ctx, + ADS_MODLIST *mods, + NT_PRINTER_DATA *data) +{ + uint32 key,val; + + for (key=0; key < data->num_keys; key++) { + REGVAL_CTR ctr = data->keys[key].values; + for (val=0; val < ctr.num_values; val++) + map_regval_to_ads(mem_ctx, mods, ctr.values[val]); + } + return True; } #endif + -- cgit From e4201bec142b6666a45c38532f1393270b6b0d48 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Mon, 18 Nov 2002 19:59:58 +0000 Subject: Next step of printer publishing. net ads printer publish [servername] Will retreive the DsSpooler and DsDriver info by rpc for a remote server then publish it. Next comes doing it within smbd (This used to be commit 8f047a4492f7bd66ac2afd2a2f6194d5dad4a434) --- source3/libads/ldap_printer.c | 348 +++++++++++++++++++++++++++++------------- 1 file changed, 242 insertions(+), 106 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index 0185bf7811..4a983b20e3 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -54,142 +54,278 @@ ADS_STATUS ads_find_printer_on_server(ADS_STRUCT *ads, void **res, } /* - modify an entire printer entry in the directory + modify a printer entry in the directory */ ADS_STATUS ads_mod_printer_entry(ADS_STRUCT *ads, char *prt_dn, - const ADS_PRINTER_ENTRY *prt) + TALLOC_CTX *ctx, const ADS_MODLIST *mods) { - ADS_MODLIST mods; - ADS_STATUS status; - TALLOC_CTX *ctx; - - if (!(ctx = talloc_init_named("mod_printer_entry"))) - return ADS_ERROR(LDAP_NO_MEMORY); - - /* allocate the list */ - mods = ads_init_mods(ctx); - - /* add the attributes to the list - required ones first */ - ads_mod_str(ctx, &mods, "printerName", prt->printerName); - ads_mod_str(ctx, &mods, "serverName", prt->serverName); - ads_mod_str(ctx, &mods, "shortServerName", prt->shortServerName); - ads_mod_str(ctx, &mods, "uNCName", prt->uNCName); - ads_mod_str(ctx, &mods, "versionNumber", prt->versionNumber); - - /* now the optional ones */ - ads_mod_strlist(ctx, &mods, "description", (const char **)prt->description); - ads_mod_str(ctx, &mods, "assetNumber",prt->assetNumber); - ads_mod_str(ctx, &mods, "bytesPerMinute",prt->bytesPerMinute); - ads_mod_str(ctx, &mods, "defaultPriority",prt->defaultPriority); - ads_mod_str(ctx, &mods, "driverName", prt->driverName); - ads_mod_str(ctx, &mods, "driverVersion",prt->driverVersion); - ads_mod_str(ctx, &mods, "location", prt->location); - ads_mod_str(ctx, &mods, "operatingSystem",prt->operatingSystem); - ads_mod_str(ctx, &mods, "operatingSystemHotfix", - prt->operatingSystemHotfix); - ads_mod_str(ctx, &mods, "operatingSystemServicePack", - prt->operatingSystemServicePack); - ads_mod_str(ctx, &mods, "operatingSystemVersion", - prt->operatingSystemVersion); - ads_mod_str(ctx, &mods, "physicalLocationObject", - prt->physicalLocationObject); - ads_mod_strlist(ctx, &mods, "portName", (const char **)prt->portName); - ads_mod_str(ctx, &mods, "printStartTime", prt->printStartTime); - ads_mod_str(ctx, &mods, "printEndTime", prt->printEndTime); - ads_mod_strlist(ctx, &mods, "printBinNames", (const char **)prt->printBinNames); - /*... and many others */ - - /* do the ldap modify */ - status = ads_gen_mod(ads, prt_dn, mods); - - /* free mod list, mods, and values */ - talloc_destroy(ctx); - - return status; + return ads_gen_mod(ads, prt_dn, *mods); } /* add a printer to the directory */ -static ADS_STATUS ads_add_printer_entry(ADS_STRUCT *ads, char *prt_dn, - const ADS_PRINTER_ENTRY *prt) +ADS_STATUS ads_add_printer_entry(ADS_STRUCT *ads, char *prt_dn, + TALLOC_CTX *ctx, ADS_MODLIST *mods) { - ADS_STATUS status; - TALLOC_CTX *ctx; - ADS_MODLIST mods; + ads_mod_str(ctx, mods, "objectClass", "printQueue"); + return ads_gen_add(ads, prt_dn, *mods); +} - if (!(ctx = talloc_init_named("add_printer_entry"))) - return ADS_ERROR(LDAP_NO_MEMORY); +/* + map a REG_SZ to an ldap mod +*/ +static BOOL map_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods, + const REGISTRY_VALUE *value) +{ + char *str_value = NULL; - if (!(mods = ads_init_mods(ctx))) - return ADS_ERROR(LDAP_NO_MEMORY); + if (value->type != REG_SZ) + return False; - /* These are the fields a printQueue must contain */ - ads_mod_str(ctx, &mods, "uNCName", prt->uNCName); - ads_mod_str(ctx, &mods, "versionNumber", prt->versionNumber); - ads_mod_str(ctx, &mods, "serverName", prt->serverName); - ads_mod_str(ctx, &mods, "shortServerName", prt->shortServerName); - ads_mod_str(ctx, &mods, "printerName", prt->printerName); - ads_mod_str(ctx, &mods, "objectClass", "printQueue"); + if (value->size && *((smb_ucs2_t *) value->data_p)) { + pull_ucs2_talloc(ctx, (void **) &str_value, + (const smb_ucs2_t *) value->data_p); + return ADS_ERR_OK(ads_mod_str(ctx, mods, value->valuename, + str_value)); + } + return True; + +} +/* + map a REG_DWORD to an ldap mod +*/ +static BOOL map_dword(TALLOC_CTX *ctx, ADS_MODLIST *mods, + const REGISTRY_VALUE *value) +{ + char *str_value = NULL; - status = ads_gen_add(ads, prt_dn, mods); + if (value->type != REG_DWORD) + return False; + str_value = talloc_asprintf(ctx, "%d", *((uint32 *) value->data_p)); + return ADS_ERR_OK(ads_mod_str(ctx, mods, value->valuename, str_value)); +} - talloc_destroy(ctx); +/* + map a boolean REG_BINARY to an ldap mod +*/ +static BOOL map_bool(TALLOC_CTX *ctx, ADS_MODLIST *mods, + const REGISTRY_VALUE *value) +{ + char *str_value; - return status; + if ((value->type != REG_BINARY) || (value->size != 1)) + return False; + str_value = talloc_asprintf(ctx, "%s", + *(value->data_p) ? "TRUE" : "FALSE"); + return ADS_ERR_OK(ads_mod_str(ctx, mods, value->valuename, str_value)); } /* - publish a printer in the ADS + map a REG_MULTI_SZ to an ldap mod */ - -ADS_STATUS ads_add_printer(ADS_STRUCT *ads, const ADS_PRINTER_ENTRY *prt) +static BOOL map_multi_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods, + const REGISTRY_VALUE *value) { - ADS_STATUS status; - void *res; - char *host_dn, *prt_dn; - const char *attrs[] = {"*", "nTSecurityDescriptor", NULL}; + char **str_values = NULL; + smb_ucs2_t *cur_str = (smb_ucs2_t *) value->data_p; + uint32 size = 0, num_vals = 0, i=0; + + if (value->type != REG_MULTI_SZ) + return False; + + while(cur_str && *cur_str && (size < value->size)) { + size += 2 * (strlen_w(cur_str) + 1); + cur_str += strlen_w(cur_str) + 1; + num_vals++; + }; + + if (num_vals) { + str_values = talloc(ctx, + (num_vals + 1) * sizeof(smb_ucs2_t *)); + memset(str_values, '\0', + (num_vals + 1) * sizeof(smb_ucs2_t *)); + + cur_str = (smb_ucs2_t *) value->data_p; + for (i=0; i < num_vals; i++) + cur_str += pull_ucs2_talloc(ctx, + (void **) &str_values[i], + cur_str); + + return ADS_ERR_OK(ads_mod_strlist(ctx, mods, value->valuename, + (const char **) str_values)); + } + return True; +} - status = ads_find_machine_acct(ads, (void **)&res, - prt->shortServerName); - if (!ADS_ERR_OK(status)) { - DEBUG(1, ("ads_add_printer: cannot find host %s in ads\n", - prt->shortServerName)); - return status; - } - host_dn = ads_get_dn(ads, res); - ads_msgfree(ads, res); - - ads_find_printer_on_server(ads, &res, prt->printerName, - prt->shortServerName); - - if (ADS_ERR_OK(status) && ads_count_replies(ads, res)) { - DEBUG(1, ("ads_add_printer: printer %s already exists\n", - prt->printerName)); - /* nothing to do, just free results */ - ads_msgfree(ads, res); - } else { - ads_msgfree(ads, res); - status = ads_add_printer_entry(ads, prt_dn, prt); - if (!ADS_ERR_OK(status)) { - DEBUG(0, ("ads_add_printer: ads_add_printer_entry failed\n")); - return status; +struct valmap_to_ads { + char *valname; + BOOL (*fn)(TALLOC_CTX *, ADS_MODLIST *, const REGISTRY_VALUE *); +}; + +/* + map a REG_SZ to an ldap mod +*/ +static void map_regval_to_ads(TALLOC_CTX *ctx, ADS_MODLIST *mods, + REGISTRY_VALUE *value) +{ + struct valmap_to_ads map[] = { + {"assetNumber", map_sz}, + {"bytesPerMinute", map_dword}, + {"defaultPriority", map_dword}, + {"driverName", map_sz}, + {"driverVersion", map_dword}, + {"flags", map_dword}, + {"location", map_sz}, + {"operatingSystem", map_sz}, + {"operatingSystemHotfix", map_sz}, + {"operatingSystemServicePack", map_sz}, + {"operatingSystemVersion", map_sz}, + {"portName", map_multi_sz}, + {"printAttributes", map_dword}, + {"printBinNames", map_multi_sz}, + {"printCollate", map_bool}, + {"printColor", map_bool}, + {"printDuplexSupported", map_bool}, + {"printEndTime", map_dword}, + {"printFormName", map_sz}, + {"printKeepPrintedJobs", map_bool}, + {"printLanguage", map_multi_sz}, + {"printMACAddress", map_sz}, + {"printMaxCopies", map_sz}, + {"printMaxResolutionSupported", map_dword}, + {"printMaxXExtent", map_dword}, + {"printMaxYExtent", map_dword}, + {"printMediaReady", map_multi_sz}, + {"printMediaSupported", map_multi_sz}, + {"printMemory", map_dword}, + {"printMinXExtent", map_dword}, + {"printMinYExtent", map_dword}, + {"printNetworkAddress", map_sz}, + {"printNotify", map_sz}, + {"printNumberUp", map_dword}, + {"printOrientationsSupported", map_multi_sz}, + {"printOwner", map_sz}, + {"printPagesPerMinute", map_dword}, + {"printRate", map_dword}, + {"printRateUnit", map_sz}, + {"printSeparatorFile", map_sz}, + {"printShareName", map_sz}, + {"printSpooling", map_sz}, + {"printStaplingSupported", map_bool}, + {"printStartTime", map_dword}, + {"printStatus", map_sz}, + {"priority", map_dword}, + {"serverName", map_sz}, + {"shortServerName", map_sz}, + {"uNCName", map_sz}, + {"url", map_sz}, + {"versionNumber", map_dword}, + {NULL, NULL} + }; + int i; + + for (i=0; map[i].valname; i++) { + if (StrCaseCmp(map[i].valname, value->valuename) == 0) { + if (!map[i].fn(ctx, mods, value)) { + DEBUG(5, ("Add of value %s to modlist failed\n", value->valuename)); + } else { + DEBUG(7, ("Mapped value %s\n", value->valuename)); + } + } } +} + - status = ads_search_dn(ads, &res, prt_dn, attrs); +WERROR get_remote_printer_publishing_data(struct cli_state *cli, + TALLOC_CTX *mem_ctx, + ADS_MODLIST *mods, + char *printer) +{ + WERROR result; + char *printername, *servername; + REGVAL_CTR dsdriver_ctr, dsspooler_ctr; + uint32 needed, i; + POLICY_HND pol; + + asprintf(&servername, "\\\\%s", cli->desthost); + asprintf(&printername, "%s\\%s", servername, printer); + if (!servername || !printername) { + DEBUG(3, ("Insufficient memory\n")); + return WERR_NOMEM; + } + + result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, + "", MAXIMUM_ALLOWED_ACCESS, + servername, cli->user_name, &pol); + if (!W_ERROR_IS_OK(result)) { + DEBUG(3, ("Unable to open printer %s, error is %s.\n", + printername, dos_errstr(result))); + return result; + } + + result = cli_spoolss_enumprinterdataex(cli, mem_ctx, 0, &needed, + &pol, "DsDriver", NULL); + + if (W_ERROR_V(result) == ERRmoredata) + result = cli_spoolss_enumprinterdataex(cli, mem_ctx, needed, + NULL, &pol, "DsDriver", + &dsdriver_ctr); + + if (!W_ERROR_IS_OK(result)) { + DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n", + printername, dos_errstr(result))); + cli_spoolss_close_printer(cli, mem_ctx, &pol); + return result; + } - if (ADS_ERR_OK(status) && ads_count_replies(ads, res)) { - /* need to retrieve GUID from results - prt->GUID */ - status = ads_mod_printer_entry(ads, prt_dn, prt); + /* Have the data we need now, so start building */ + + for (i=0; i < dsdriver_ctr.num_values; i++) + map_regval_to_ads(mem_ctx, mods, dsdriver_ctr.values[i]); + + result = cli_spoolss_enumprinterdataex(cli, mem_ctx, 0, &needed, + &pol, "DsSpooler", NULL); + + if (W_ERROR_V(result) == ERRmoredata) + result = cli_spoolss_enumprinterdataex(cli, mem_ctx, needed, + NULL, &pol, "DsSpooler", + &dsspooler_ctr); + + if (!W_ERROR_IS_OK(result)) { + DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n", + printername, dos_errstr(result))); + regval_ctr_destroy(&dsdriver_ctr); + cli_spoolss_close_printer(cli, mem_ctx, &pol); + return result; } + for (i=0; i < dsspooler_ctr.num_values; i++) + map_regval_to_ads(mem_ctx, mods, dsspooler_ctr.values[i]); + + ads_mod_str(mem_ctx, mods, "printerName", printername); - ads_msgfree(ads, res); + regval_ctr_destroy(&dsdriver_ctr); + regval_ctr_destroy(&dsspooler_ctr); + cli_spoolss_close_printer(cli, mem_ctx, &pol); + return result; +} - return status; +BOOL get_local_printer_publishing_data(TALLOC_CTX *mem_ctx, + ADS_MODLIST *mods, + NT_PRINTER_DATA *data) +{ + uint32 key,val; + + for (key=0; key < data->num_keys; key++) { + REGVAL_CTR ctr = data->keys[key].values; + for (val=0; val < ctr.num_values; val++) + map_regval_to_ads(mem_ctx, mods, ctr.values[val]); + } + return True; } #endif + -- cgit From bf909c0c368adcd92d9cffa637257f82c950413b Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Mon, 18 Nov 2002 20:45:46 +0000 Subject: Don't pass a function to ADS_ERR_OK(). (This used to be commit dff4c93d85717ba29799a0ebaaba8b8539c8d68d) --- source3/libads/ldap_printer.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index 4a983b20e3..1edc933683 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -79,6 +79,7 @@ static BOOL map_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods, const REGISTRY_VALUE *value) { char *str_value = NULL; + ADS_STATUS status; if (value->type != REG_SZ) return False; @@ -86,8 +87,8 @@ static BOOL map_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods, if (value->size && *((smb_ucs2_t *) value->data_p)) { pull_ucs2_talloc(ctx, (void **) &str_value, (const smb_ucs2_t *) value->data_p); - return ADS_ERR_OK(ads_mod_str(ctx, mods, value->valuename, - str_value)); + status = ads_mod_str(ctx, mods, value->valuename, str_value); + return ADS_ERR_OK(status); } return True; @@ -100,11 +101,13 @@ static BOOL map_dword(TALLOC_CTX *ctx, ADS_MODLIST *mods, const REGISTRY_VALUE *value) { char *str_value = NULL; + ADS_STATUS status; if (value->type != REG_DWORD) return False; str_value = talloc_asprintf(ctx, "%d", *((uint32 *) value->data_p)); - return ADS_ERR_OK(ads_mod_str(ctx, mods, value->valuename, str_value)); + status = ads_mod_str(ctx, mods, value->valuename, str_value); + return ADS_ERR_OK(status); } /* @@ -114,12 +117,14 @@ static BOOL map_bool(TALLOC_CTX *ctx, ADS_MODLIST *mods, const REGISTRY_VALUE *value) { char *str_value; + ADS_STATUS status; if ((value->type != REG_BINARY) || (value->size != 1)) return False; str_value = talloc_asprintf(ctx, "%s", *(value->data_p) ? "TRUE" : "FALSE"); - return ADS_ERR_OK(ads_mod_str(ctx, mods, value->valuename, str_value)); + status = ads_mod_str(ctx, mods, value->valuename, str_value); + return ADS_ERR_OK(status); } /* @@ -131,6 +136,7 @@ static BOOL map_multi_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods, char **str_values = NULL; smb_ucs2_t *cur_str = (smb_ucs2_t *) value->data_p; uint32 size = 0, num_vals = 0, i=0; + ADS_STATUS status; if (value->type != REG_MULTI_SZ) return False; @@ -153,8 +159,9 @@ static BOOL map_multi_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods, (void **) &str_values[i], cur_str); - return ADS_ERR_OK(ads_mod_strlist(ctx, mods, value->valuename, - (const char **) str_values)); + status = ads_mod_strlist(ctx, mods, value->valuename, + (const char **) str_values); + return ADS_ERR_OK(status); } return True; } -- cgit From 713b2f0b4741ce898beee056a9b15c46a7bf081e Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Mon, 18 Nov 2002 20:46:20 +0000 Subject: Don't pass a function to ADS_ERR_OK(). (This used to be commit a148e4c290820a48c8b51e0e0459b2171b32c258) --- source3/libads/ldap_printer.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index 4a983b20e3..1edc933683 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -79,6 +79,7 @@ static BOOL map_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods, const REGISTRY_VALUE *value) { char *str_value = NULL; + ADS_STATUS status; if (value->type != REG_SZ) return False; @@ -86,8 +87,8 @@ static BOOL map_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods, if (value->size && *((smb_ucs2_t *) value->data_p)) { pull_ucs2_talloc(ctx, (void **) &str_value, (const smb_ucs2_t *) value->data_p); - return ADS_ERR_OK(ads_mod_str(ctx, mods, value->valuename, - str_value)); + status = ads_mod_str(ctx, mods, value->valuename, str_value); + return ADS_ERR_OK(status); } return True; @@ -100,11 +101,13 @@ static BOOL map_dword(TALLOC_CTX *ctx, ADS_MODLIST *mods, const REGISTRY_VALUE *value) { char *str_value = NULL; + ADS_STATUS status; if (value->type != REG_DWORD) return False; str_value = talloc_asprintf(ctx, "%d", *((uint32 *) value->data_p)); - return ADS_ERR_OK(ads_mod_str(ctx, mods, value->valuename, str_value)); + status = ads_mod_str(ctx, mods, value->valuename, str_value); + return ADS_ERR_OK(status); } /* @@ -114,12 +117,14 @@ static BOOL map_bool(TALLOC_CTX *ctx, ADS_MODLIST *mods, const REGISTRY_VALUE *value) { char *str_value; + ADS_STATUS status; if ((value->type != REG_BINARY) || (value->size != 1)) return False; str_value = talloc_asprintf(ctx, "%s", *(value->data_p) ? "TRUE" : "FALSE"); - return ADS_ERR_OK(ads_mod_str(ctx, mods, value->valuename, str_value)); + status = ads_mod_str(ctx, mods, value->valuename, str_value); + return ADS_ERR_OK(status); } /* @@ -131,6 +136,7 @@ static BOOL map_multi_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods, char **str_values = NULL; smb_ucs2_t *cur_str = (smb_ucs2_t *) value->data_p; uint32 size = 0, num_vals = 0, i=0; + ADS_STATUS status; if (value->type != REG_MULTI_SZ) return False; @@ -153,8 +159,9 @@ static BOOL map_multi_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods, (void **) &str_values[i], cur_str); - return ADS_ERR_OK(ads_mod_strlist(ctx, mods, value->valuename, - (const char **) str_values)); + status = ads_mod_strlist(ctx, mods, value->valuename, + (const char **) str_values); + return ADS_ERR_OK(status); } return True; } -- cgit From 191dff2d279dd8315f093e313d8c149e786eb19f Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Sat, 23 Nov 2002 14:27:56 +0000 Subject: [merge from APP_HEAD] 90% fix for CR 1076. The password server parameter will no take things like password server = DC1 * which means to contact DC1 first and the go to auto lookup if it fails. jerry (This used to be commit c31a17889e3e4daf7c1e807038efc2c0fba78be3) --- source3/libads/ldap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 60427323b0..fcb96dd174 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -186,6 +186,7 @@ static BOOL ads_try_netbios(ADS_STRUCT *ads) int count; int i; const char *workgroup = ads->server.workgroup; + BOOL list_ordered; if (!workgroup) { workgroup = lp_workgroup(); @@ -202,7 +203,7 @@ static BOOL ads_try_netbios(ADS_STRUCT *ads) } /* now any DC, including backups */ - if (get_dc_list(workgroup, &ip_list, &count)) { + if (get_dc_list(workgroup, &ip_list, &count, &list_ordered)) { for (i=0;i Date: Sat, 23 Nov 2002 14:52:34 +0000 Subject: [merge from APP_HEAD] 90% fix for CR 1076. The password server parameter will no take things like password server = DC1 * which means to contact DC1 first and the go to auto lookup if it fails. jerry (This used to be commit 016ef8b36b30846311a5321803298f8e28719244) --- source3/libads/ldap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 60427323b0..fcb96dd174 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -186,6 +186,7 @@ static BOOL ads_try_netbios(ADS_STRUCT *ads) int count; int i; const char *workgroup = ads->server.workgroup; + BOOL list_ordered; if (!workgroup) { workgroup = lp_workgroup(); @@ -202,7 +203,7 @@ static BOOL ads_try_netbios(ADS_STRUCT *ads) } /* now any DC, including backups */ - if (get_dc_list(workgroup, &ip_list, &count)) { + if (get_dc_list(workgroup, &ip_list, &count, &list_ordered)) { for (i=0;i Date: Tue, 3 Dec 2002 19:41:43 +0000 Subject: Stop using hardcoded key/value strings, be more forgiving of dsspooler/dsdriver info existence. (This used to be commit ca8735532cb656a09c1586326cdce33984fe38b4) --- source3/libads/ldap_printer.c | 144 ++++++++++++++++++++++-------------------- 1 file changed, 74 insertions(+), 70 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index 1edc933683..a8c1148093 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -178,57 +178,57 @@ static void map_regval_to_ads(TALLOC_CTX *ctx, ADS_MODLIST *mods, REGISTRY_VALUE *value) { struct valmap_to_ads map[] = { - {"assetNumber", map_sz}, - {"bytesPerMinute", map_dword}, - {"defaultPriority", map_dword}, - {"driverName", map_sz}, - {"driverVersion", map_dword}, - {"flags", map_dword}, - {"location", map_sz}, - {"operatingSystem", map_sz}, - {"operatingSystemHotfix", map_sz}, - {"operatingSystemServicePack", map_sz}, - {"operatingSystemVersion", map_sz}, - {"portName", map_multi_sz}, - {"printAttributes", map_dword}, - {"printBinNames", map_multi_sz}, - {"printCollate", map_bool}, - {"printColor", map_bool}, - {"printDuplexSupported", map_bool}, - {"printEndTime", map_dword}, - {"printFormName", map_sz}, - {"printKeepPrintedJobs", map_bool}, - {"printLanguage", map_multi_sz}, - {"printMACAddress", map_sz}, - {"printMaxCopies", map_sz}, - {"printMaxResolutionSupported", map_dword}, - {"printMaxXExtent", map_dword}, - {"printMaxYExtent", map_dword}, - {"printMediaReady", map_multi_sz}, - {"printMediaSupported", map_multi_sz}, - {"printMemory", map_dword}, - {"printMinXExtent", map_dword}, - {"printMinYExtent", map_dword}, - {"printNetworkAddress", map_sz}, - {"printNotify", map_sz}, - {"printNumberUp", map_dword}, - {"printOrientationsSupported", map_multi_sz}, - {"printOwner", map_sz}, - {"printPagesPerMinute", map_dword}, - {"printRate", map_dword}, - {"printRateUnit", map_sz}, - {"printSeparatorFile", map_sz}, - {"printShareName", map_sz}, - {"printSpooling", map_sz}, - {"printStaplingSupported", map_bool}, - {"printStartTime", map_dword}, - {"printStatus", map_sz}, - {"priority", map_dword}, - {"serverName", map_sz}, - {"shortServerName", map_sz}, - {"uNCName", map_sz}, - {"url", map_sz}, - {"versionNumber", map_dword}, + {SPOOL_REG_ASSETNUMBER, map_sz}, + {SPOOL_REG_BYTESPERMINUTE, map_dword}, + {SPOOL_REG_DEFAULTPRIORITY, map_dword}, + {SPOOL_REG_DRIVERNAME, map_sz}, + {SPOOL_REG_DRIVERVERSION, map_dword}, + {SPOOL_REG_FLAGS, map_dword}, + {SPOOL_REG_LOCATION, map_sz}, + {SPOOL_REG_OPERATINGSYSTEM, map_sz}, + {SPOOL_REG_OPERATINGSYSTEMHOTFIX, map_sz}, + {SPOOL_REG_OPERATINGSYSTEMSERVICEPACK, map_sz}, + {SPOOL_REG_OPERATINGSYSTEMVERSION, map_sz}, + {SPOOL_REG_PORTNAME, map_multi_sz}, + {SPOOL_REG_PRINTATTRIBUTES, map_dword}, + {SPOOL_REG_PRINTBINNAMES, map_multi_sz}, + {SPOOL_REG_PRINTCOLLATE, map_bool}, + {SPOOL_REG_PRINTCOLOR, map_bool}, + {SPOOL_REG_PRINTDUPLEXSUPPORTED, map_bool}, + {SPOOL_REG_PRINTENDTIME, map_dword}, + {SPOOL_REG_PRINTFORMNAME, map_sz}, + {SPOOL_REG_PRINTKEEPPRINTEDJOBS, map_bool}, + {SPOOL_REG_PRINTLANGUAGE, map_multi_sz}, + {SPOOL_REG_PRINTMACADDRESS, map_sz}, + {SPOOL_REG_PRINTMAXCOPIES, map_sz}, + {SPOOL_REG_PRINTMAXRESOLUTIONSUPPORTED, map_dword}, + {SPOOL_REG_PRINTMAXXEXTENT, map_dword}, + {SPOOL_REG_PRINTMAXYEXTENT, map_dword}, + {SPOOL_REG_PRINTMEDIAREADY, map_multi_sz}, + {SPOOL_REG_PRINTMEDIASUPPORTED, map_multi_sz}, + {SPOOL_REG_PRINTMEMORY, map_dword}, + {SPOOL_REG_PRINTMINXEXTENT, map_dword}, + {SPOOL_REG_PRINTMINYEXTENT, map_dword}, + {SPOOL_REG_PRINTNETWORKADDRESS, map_sz}, + {SPOOL_REG_PRINTNOTIFY, map_sz}, + {SPOOL_REG_PRINTNUMBERUP, map_dword}, + {SPOOL_REG_PRINTORIENTATIONSSUPPORTED, map_multi_sz}, + {SPOOL_REG_PRINTOWNER, map_sz}, + {SPOOL_REG_PRINTPAGESPERMINUTE, map_dword}, + {SPOOL_REG_PRINTRATE, map_dword}, + {SPOOL_REG_PRINTRATEUNIT, map_sz}, + {SPOOL_REG_PRINTSEPARATORFILE, map_sz}, + {SPOOL_REG_PRINTSHARENAME, map_sz}, + {SPOOL_REG_PRINTSPOOLING, map_sz}, + {SPOOL_REG_PRINTSTAPLINGSUPPORTED, map_bool}, + {SPOOL_REG_PRINTSTARTTIME, map_dword}, + {SPOOL_REG_PRINTSTATUS, map_sz}, + {SPOOL_REG_PRIORITY, map_dword}, + {SPOOL_REG_SERVERNAME, map_sz}, + {SPOOL_REG_SHORTSERVERNAME, map_sz}, + {SPOOL_REG_UNCNAME, map_sz}, + {SPOOL_REG_URL, map_sz}, + {SPOOL_REG_VERSIONNUMBER, map_dword}, {NULL, NULL} }; int i; @@ -254,6 +254,7 @@ WERROR get_remote_printer_publishing_data(struct cli_state *cli, WERROR result; char *printername, *servername; REGVAL_CTR dsdriver_ctr, dsspooler_ctr; + BOOL got_dsdriver = False, got_dsspooler = False; uint32 needed, i; POLICY_HND pol; @@ -274,47 +275,50 @@ WERROR get_remote_printer_publishing_data(struct cli_state *cli, } result = cli_spoolss_enumprinterdataex(cli, mem_ctx, 0, &needed, - &pol, "DsDriver", NULL); + &pol, SPOOL_DSDRIVER_KEY, NULL); if (W_ERROR_V(result) == ERRmoredata) result = cli_spoolss_enumprinterdataex(cli, mem_ctx, needed, - NULL, &pol, "DsDriver", + NULL, &pol, + SPOOL_DSDRIVER_KEY, &dsdriver_ctr); if (!W_ERROR_IS_OK(result)) { DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n", printername, dos_errstr(result))); - cli_spoolss_close_printer(cli, mem_ctx, &pol); - return result; - } - - /* Have the data we need now, so start building */ + } else { - for (i=0; i < dsdriver_ctr.num_values; i++) - map_regval_to_ads(mem_ctx, mods, dsdriver_ctr.values[i]); + /* Have the data we need now, so start building */ + got_dsdriver = True; + for (i=0; i < dsdriver_ctr.num_values; i++) + map_regval_to_ads(mem_ctx, mods, + dsdriver_ctr.values[i]); + } result = cli_spoolss_enumprinterdataex(cli, mem_ctx, 0, &needed, - &pol, "DsSpooler", NULL); + &pol, SPOOL_DSSPOOLER_KEY, + NULL); if (W_ERROR_V(result) == ERRmoredata) result = cli_spoolss_enumprinterdataex(cli, mem_ctx, needed, - NULL, &pol, "DsSpooler", + NULL, &pol, + SPOOL_DSSPOOLER_KEY, &dsspooler_ctr); if (!W_ERROR_IS_OK(result)) { DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n", printername, dos_errstr(result))); - regval_ctr_destroy(&dsdriver_ctr); - cli_spoolss_close_printer(cli, mem_ctx, &pol); - return result; + } else { + got_dsspooler = True; + for (i=0; i < dsspooler_ctr.num_values; i++) + map_regval_to_ads(mem_ctx, mods, + dsspooler_ctr.values[i]); } - for (i=0; i < dsspooler_ctr.num_values; i++) - map_regval_to_ads(mem_ctx, mods, dsspooler_ctr.values[i]); - ads_mod_str(mem_ctx, mods, "printerName", printername); + ads_mod_str(mem_ctx, mods, SPOOL_REG_PRINTERNAME, printer); - regval_ctr_destroy(&dsdriver_ctr); - regval_ctr_destroy(&dsspooler_ctr); + if (got_dsdriver) regval_ctr_destroy(&dsdriver_ctr); + if (got_dsspooler) regval_ctr_destroy(&dsspooler_ctr); cli_spoolss_close_printer(cli, mem_ctx, &pol); return result; -- cgit From 2e2f58fded84099f5d65ce0d0d53899a27557895 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Tue, 3 Dec 2002 19:42:39 +0000 Subject: Stop using hardcoded key/value strings, be more forgiving of dsspooler/dsdriver info existence. (This used to be commit 59ced15a1b0d88a24a89b3aa9717599aa110272b) --- source3/libads/ldap_printer.c | 144 ++++++++++++++++++++++-------------------- 1 file changed, 74 insertions(+), 70 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index 1edc933683..a8c1148093 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -178,57 +178,57 @@ static void map_regval_to_ads(TALLOC_CTX *ctx, ADS_MODLIST *mods, REGISTRY_VALUE *value) { struct valmap_to_ads map[] = { - {"assetNumber", map_sz}, - {"bytesPerMinute", map_dword}, - {"defaultPriority", map_dword}, - {"driverName", map_sz}, - {"driverVersion", map_dword}, - {"flags", map_dword}, - {"location", map_sz}, - {"operatingSystem", map_sz}, - {"operatingSystemHotfix", map_sz}, - {"operatingSystemServicePack", map_sz}, - {"operatingSystemVersion", map_sz}, - {"portName", map_multi_sz}, - {"printAttributes", map_dword}, - {"printBinNames", map_multi_sz}, - {"printCollate", map_bool}, - {"printColor", map_bool}, - {"printDuplexSupported", map_bool}, - {"printEndTime", map_dword}, - {"printFormName", map_sz}, - {"printKeepPrintedJobs", map_bool}, - {"printLanguage", map_multi_sz}, - {"printMACAddress", map_sz}, - {"printMaxCopies", map_sz}, - {"printMaxResolutionSupported", map_dword}, - {"printMaxXExtent", map_dword}, - {"printMaxYExtent", map_dword}, - {"printMediaReady", map_multi_sz}, - {"printMediaSupported", map_multi_sz}, - {"printMemory", map_dword}, - {"printMinXExtent", map_dword}, - {"printMinYExtent", map_dword}, - {"printNetworkAddress", map_sz}, - {"printNotify", map_sz}, - {"printNumberUp", map_dword}, - {"printOrientationsSupported", map_multi_sz}, - {"printOwner", map_sz}, - {"printPagesPerMinute", map_dword}, - {"printRate", map_dword}, - {"printRateUnit", map_sz}, - {"printSeparatorFile", map_sz}, - {"printShareName", map_sz}, - {"printSpooling", map_sz}, - {"printStaplingSupported", map_bool}, - {"printStartTime", map_dword}, - {"printStatus", map_sz}, - {"priority", map_dword}, - {"serverName", map_sz}, - {"shortServerName", map_sz}, - {"uNCName", map_sz}, - {"url", map_sz}, - {"versionNumber", map_dword}, + {SPOOL_REG_ASSETNUMBER, map_sz}, + {SPOOL_REG_BYTESPERMINUTE, map_dword}, + {SPOOL_REG_DEFAULTPRIORITY, map_dword}, + {SPOOL_REG_DRIVERNAME, map_sz}, + {SPOOL_REG_DRIVERVERSION, map_dword}, + {SPOOL_REG_FLAGS, map_dword}, + {SPOOL_REG_LOCATION, map_sz}, + {SPOOL_REG_OPERATINGSYSTEM, map_sz}, + {SPOOL_REG_OPERATINGSYSTEMHOTFIX, map_sz}, + {SPOOL_REG_OPERATINGSYSTEMSERVICEPACK, map_sz}, + {SPOOL_REG_OPERATINGSYSTEMVERSION, map_sz}, + {SPOOL_REG_PORTNAME, map_multi_sz}, + {SPOOL_REG_PRINTATTRIBUTES, map_dword}, + {SPOOL_REG_PRINTBINNAMES, map_multi_sz}, + {SPOOL_REG_PRINTCOLLATE, map_bool}, + {SPOOL_REG_PRINTCOLOR, map_bool}, + {SPOOL_REG_PRINTDUPLEXSUPPORTED, map_bool}, + {SPOOL_REG_PRINTENDTIME, map_dword}, + {SPOOL_REG_PRINTFORMNAME, map_sz}, + {SPOOL_REG_PRINTKEEPPRINTEDJOBS, map_bool}, + {SPOOL_REG_PRINTLANGUAGE, map_multi_sz}, + {SPOOL_REG_PRINTMACADDRESS, map_sz}, + {SPOOL_REG_PRINTMAXCOPIES, map_sz}, + {SPOOL_REG_PRINTMAXRESOLUTIONSUPPORTED, map_dword}, + {SPOOL_REG_PRINTMAXXEXTENT, map_dword}, + {SPOOL_REG_PRINTMAXYEXTENT, map_dword}, + {SPOOL_REG_PRINTMEDIAREADY, map_multi_sz}, + {SPOOL_REG_PRINTMEDIASUPPORTED, map_multi_sz}, + {SPOOL_REG_PRINTMEMORY, map_dword}, + {SPOOL_REG_PRINTMINXEXTENT, map_dword}, + {SPOOL_REG_PRINTMINYEXTENT, map_dword}, + {SPOOL_REG_PRINTNETWORKADDRESS, map_sz}, + {SPOOL_REG_PRINTNOTIFY, map_sz}, + {SPOOL_REG_PRINTNUMBERUP, map_dword}, + {SPOOL_REG_PRINTORIENTATIONSSUPPORTED, map_multi_sz}, + {SPOOL_REG_PRINTOWNER, map_sz}, + {SPOOL_REG_PRINTPAGESPERMINUTE, map_dword}, + {SPOOL_REG_PRINTRATE, map_dword}, + {SPOOL_REG_PRINTRATEUNIT, map_sz}, + {SPOOL_REG_PRINTSEPARATORFILE, map_sz}, + {SPOOL_REG_PRINTSHARENAME, map_sz}, + {SPOOL_REG_PRINTSPOOLING, map_sz}, + {SPOOL_REG_PRINTSTAPLINGSUPPORTED, map_bool}, + {SPOOL_REG_PRINTSTARTTIME, map_dword}, + {SPOOL_REG_PRINTSTATUS, map_sz}, + {SPOOL_REG_PRIORITY, map_dword}, + {SPOOL_REG_SERVERNAME, map_sz}, + {SPOOL_REG_SHORTSERVERNAME, map_sz}, + {SPOOL_REG_UNCNAME, map_sz}, + {SPOOL_REG_URL, map_sz}, + {SPOOL_REG_VERSIONNUMBER, map_dword}, {NULL, NULL} }; int i; @@ -254,6 +254,7 @@ WERROR get_remote_printer_publishing_data(struct cli_state *cli, WERROR result; char *printername, *servername; REGVAL_CTR dsdriver_ctr, dsspooler_ctr; + BOOL got_dsdriver = False, got_dsspooler = False; uint32 needed, i; POLICY_HND pol; @@ -274,47 +275,50 @@ WERROR get_remote_printer_publishing_data(struct cli_state *cli, } result = cli_spoolss_enumprinterdataex(cli, mem_ctx, 0, &needed, - &pol, "DsDriver", NULL); + &pol, SPOOL_DSDRIVER_KEY, NULL); if (W_ERROR_V(result) == ERRmoredata) result = cli_spoolss_enumprinterdataex(cli, mem_ctx, needed, - NULL, &pol, "DsDriver", + NULL, &pol, + SPOOL_DSDRIVER_KEY, &dsdriver_ctr); if (!W_ERROR_IS_OK(result)) { DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n", printername, dos_errstr(result))); - cli_spoolss_close_printer(cli, mem_ctx, &pol); - return result; - } - - /* Have the data we need now, so start building */ + } else { - for (i=0; i < dsdriver_ctr.num_values; i++) - map_regval_to_ads(mem_ctx, mods, dsdriver_ctr.values[i]); + /* Have the data we need now, so start building */ + got_dsdriver = True; + for (i=0; i < dsdriver_ctr.num_values; i++) + map_regval_to_ads(mem_ctx, mods, + dsdriver_ctr.values[i]); + } result = cli_spoolss_enumprinterdataex(cli, mem_ctx, 0, &needed, - &pol, "DsSpooler", NULL); + &pol, SPOOL_DSSPOOLER_KEY, + NULL); if (W_ERROR_V(result) == ERRmoredata) result = cli_spoolss_enumprinterdataex(cli, mem_ctx, needed, - NULL, &pol, "DsSpooler", + NULL, &pol, + SPOOL_DSSPOOLER_KEY, &dsspooler_ctr); if (!W_ERROR_IS_OK(result)) { DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n", printername, dos_errstr(result))); - regval_ctr_destroy(&dsdriver_ctr); - cli_spoolss_close_printer(cli, mem_ctx, &pol); - return result; + } else { + got_dsspooler = True; + for (i=0; i < dsspooler_ctr.num_values; i++) + map_regval_to_ads(mem_ctx, mods, + dsspooler_ctr.values[i]); } - for (i=0; i < dsspooler_ctr.num_values; i++) - map_regval_to_ads(mem_ctx, mods, dsspooler_ctr.values[i]); - ads_mod_str(mem_ctx, mods, "printerName", printername); + ads_mod_str(mem_ctx, mods, SPOOL_REG_PRINTERNAME, printer); - regval_ctr_destroy(&dsdriver_ctr); - regval_ctr_destroy(&dsspooler_ctr); + if (got_dsdriver) regval_ctr_destroy(&dsdriver_ctr); + if (got_dsspooler) regval_ctr_destroy(&dsspooler_ctr); cli_spoolss_close_printer(cli, mem_ctx, &pol); return result; -- cgit From 90d9cf973e92510ba8e0b5c9cade65fa2cf55246 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Thu, 5 Dec 2002 19:13:20 +0000 Subject: More printer data to publish (This used to be commit 82f3a786bf01878629fe4c05b028ae8d58eb4394) --- source3/libads/ldap_printer.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index a8c1148093..b2ee5f2265 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -181,6 +181,7 @@ static void map_regval_to_ads(TALLOC_CTX *ctx, ADS_MODLIST *mods, {SPOOL_REG_ASSETNUMBER, map_sz}, {SPOOL_REG_BYTESPERMINUTE, map_dword}, {SPOOL_REG_DEFAULTPRIORITY, map_dword}, + {SPOOL_REG_DESCRIPTION, map_sz}, {SPOOL_REG_DRIVERNAME, map_sz}, {SPOOL_REG_DRIVERVERSION, map_dword}, {SPOOL_REG_FLAGS, map_dword}, -- cgit From 26236b30d09ebf31e43911f2d7cbec80df519b71 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Thu, 5 Dec 2002 19:13:40 +0000 Subject: More printer data to publish (This used to be commit 6e2f0c4e304a09313f933a3c9c2a7b3a0219006d) --- source3/libads/ldap_printer.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index a8c1148093..b2ee5f2265 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -181,6 +181,7 @@ static void map_regval_to_ads(TALLOC_CTX *ctx, ADS_MODLIST *mods, {SPOOL_REG_ASSETNUMBER, map_sz}, {SPOOL_REG_BYTESPERMINUTE, map_dword}, {SPOOL_REG_DEFAULTPRIORITY, map_dword}, + {SPOOL_REG_DESCRIPTION, map_sz}, {SPOOL_REG_DRIVERNAME, map_sz}, {SPOOL_REG_DRIVERVERSION, map_dword}, {SPOOL_REG_FLAGS, map_dword}, -- cgit From bfd8043a403dfed84bc568685580703a8470738d Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 13 Dec 2002 18:56:48 +0000 Subject: More printer publishing code. - Add published attribute to info2, needed for win clients to work properly - Return proper info on getprinter 7 This means you can now look at the sharing tab of a printer and get correct info about whether it is published or not, and change it. (This used to be commit adda04379ee46f105436262663652f3f576fa3cf) --- source3/libads/ldap.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index fcb96dd174..af9a6451fe 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1581,6 +1581,32 @@ BOOL ads_pull_uint32(ADS_STRUCT *ads, return True; } +/** + * pull a single objectGUID from an ADS result + * @param ads connection to ADS server + * @param msg results of search + * @param guid 37-byte area to receive text guid + * @return boolean indicating success + **/ +BOOL ads_pull_guid(ADS_STRUCT *ads, + void *msg, GUID *guid) +{ + char **values; + + values = ldap_get_values(ads->ld, msg, "objectGUID"); + if (!values) return False; + + if (values[0]) { + memcpy(guid, values[0], sizeof(GUID)); + ldap_value_free(values); + return True; + } + ldap_value_free(values); + return False; + +} + + /** * pull a single DOM_SID from a ADS result * @param ads connection to ads server -- cgit From 81a2a307392a12e5ec464e524d2948611e23b943 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 13 Dec 2002 19:01:27 +0000 Subject: More printer publishing code. - Add published attribute to info2, needed for win clients to work properly - Return proper info on getprinter 7 This means you can now look at the sharing tab of a printer and get correct info about whether it is published or not, and change it. (This used to be commit d57bddc9b22e809c79294c7eacbd5d0f115fe990) --- source3/libads/ldap.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index fcb96dd174..af9a6451fe 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1581,6 +1581,32 @@ BOOL ads_pull_uint32(ADS_STRUCT *ads, return True; } +/** + * pull a single objectGUID from an ADS result + * @param ads connection to ADS server + * @param msg results of search + * @param guid 37-byte area to receive text guid + * @return boolean indicating success + **/ +BOOL ads_pull_guid(ADS_STRUCT *ads, + void *msg, GUID *guid) +{ + char **values; + + values = ldap_get_values(ads->ld, msg, "objectGUID"); + if (!values) return False; + + if (values[0]) { + memcpy(guid, values[0], sizeof(GUID)); + ldap_value_free(values); + return True; + } + ldap_value_free(values); + return False; + +} + + /** * pull a single DOM_SID from a ADS result * @param ads connection to ads server -- cgit From ef8bd7c4f7ae8192ea05db070962ecf0ff3615f3 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 20 Dec 2002 20:21:31 +0000 Subject: Forward port the change to talloc_init() to make all talloc contexts named. Ensure we can query them. Jeremy. (This used to be commit 09a218a9f6fb0bd922940467bf8500eb4f1bcf84) --- source3/libads/ldap.c | 14 +++++++------- source3/libads/ldap_user.c | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index af9a6451fe..97ccf76983 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -420,7 +420,7 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, *res = NULL; - if (!(ctx = talloc_init())) + if (!(ctx = talloc_init("ads_do_paged_search"))) return ADS_ERROR(LDAP_NO_MEMORY); /* 0 means the conversion worked but the result was empty @@ -642,7 +642,7 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, char *utf8_exp, *utf8_path, **search_attrs = NULL; TALLOC_CTX *ctx; - if (!(ctx = talloc_init())) { + if (!(ctx = talloc_init("ads_do_search"))) { DEBUG(1,("ads_do_search: talloc_init() failed!")); return ADS_ERROR(LDAP_NO_MEMORY); } @@ -1031,7 +1031,7 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, char *psp; unsigned acct_control; - if (!(ctx = talloc_init_named("machine_account"))) + if (!(ctx = talloc_init("machine_account"))) return ADS_ERROR(LDAP_NO_MEMORY); ret = ADS_ERROR(LDAP_NO_MEMORY); @@ -1144,7 +1144,7 @@ static void dump_sd(const char *filed, struct berval **values) SEC_DESC *psd = 0; TALLOC_CTX *ctx = 0; - if (!(ctx = talloc_init_named("sec_io_desc"))) + if (!(ctx = talloc_init("sec_io_desc"))) return; /* prepare data */ @@ -1246,7 +1246,7 @@ void ads_process_results(ADS_STRUCT *ads, void *res, void *msg; TALLOC_CTX *ctx; - if (!(ctx = talloc_init())) + if (!(ctx = talloc_init("ads_process_results"))) return; for (msg = ads_first_entry(ads, res); msg; @@ -1429,7 +1429,7 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) msg = ads_first_entry(ads, res); ads_pull_sid(ads, msg, attrs[1], &sid); - if (!(ctx = talloc_init_named("sec_io_desc"))) { + if (!(ctx = talloc_init("sec_io_desc"))) { ret = ADS_ERROR(LDAP_NO_MEMORY); goto ads_set_sd_error; } @@ -1785,7 +1785,7 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads) char *timestr; TALLOC_CTX *ctx; - if (!(ctx = talloc_init())) { + if (!(ctx = talloc_init("ads_server_info"))) { return ADS_ERROR(LDAP_NO_MEMORY); } diff --git a/source3/libads/ldap_user.c b/source3/libads/ldap_user.c index b6fef24b5c..de19e2da5e 100644 --- a/source3/libads/ldap_user.c +++ b/source3/libads/ldap_user.c @@ -50,7 +50,7 @@ ADS_STATUS ads_add_user_acct(ADS_STRUCT *ads, const char *user, if (fullname && *fullname) name = fullname; else name = user; - if (!(ctx = talloc_init_named("ads_add_user_acct"))) + if (!(ctx = talloc_init("ads_add_user_acct"))) return ADS_ERROR(LDAP_NO_MEMORY); status = ADS_ERROR(LDAP_NO_MEMORY); @@ -88,7 +88,7 @@ ADS_STATUS ads_add_group_acct(ADS_STRUCT *ads, const char *group, char *new_dn; const char *objectClass[] = {"top", "group", NULL}; - if (!(ctx = talloc_init_named("ads_add_group_acct"))) + if (!(ctx = talloc_init("ads_add_group_acct"))) return ADS_ERROR(LDAP_NO_MEMORY); status = ADS_ERROR(LDAP_NO_MEMORY); -- cgit From 7f23546730e49569d41a5edd0c47bb559c4f812d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 20 Dec 2002 20:23:06 +0000 Subject: Forward port the change to talloc_init() to make all talloc contexts named. Ensure we can query them. Jeremy. (This used to be commit 842e08e52a665ae678eea239759bb2de1a0d7b33) --- source3/libads/ldap.c | 14 +++++++------- source3/libads/ldap_user.c | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index af9a6451fe..97ccf76983 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -420,7 +420,7 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, *res = NULL; - if (!(ctx = talloc_init())) + if (!(ctx = talloc_init("ads_do_paged_search"))) return ADS_ERROR(LDAP_NO_MEMORY); /* 0 means the conversion worked but the result was empty @@ -642,7 +642,7 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, char *utf8_exp, *utf8_path, **search_attrs = NULL; TALLOC_CTX *ctx; - if (!(ctx = talloc_init())) { + if (!(ctx = talloc_init("ads_do_search"))) { DEBUG(1,("ads_do_search: talloc_init() failed!")); return ADS_ERROR(LDAP_NO_MEMORY); } @@ -1031,7 +1031,7 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, char *psp; unsigned acct_control; - if (!(ctx = talloc_init_named("machine_account"))) + if (!(ctx = talloc_init("machine_account"))) return ADS_ERROR(LDAP_NO_MEMORY); ret = ADS_ERROR(LDAP_NO_MEMORY); @@ -1144,7 +1144,7 @@ static void dump_sd(const char *filed, struct berval **values) SEC_DESC *psd = 0; TALLOC_CTX *ctx = 0; - if (!(ctx = talloc_init_named("sec_io_desc"))) + if (!(ctx = talloc_init("sec_io_desc"))) return; /* prepare data */ @@ -1246,7 +1246,7 @@ void ads_process_results(ADS_STRUCT *ads, void *res, void *msg; TALLOC_CTX *ctx; - if (!(ctx = talloc_init())) + if (!(ctx = talloc_init("ads_process_results"))) return; for (msg = ads_first_entry(ads, res); msg; @@ -1429,7 +1429,7 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) msg = ads_first_entry(ads, res); ads_pull_sid(ads, msg, attrs[1], &sid); - if (!(ctx = talloc_init_named("sec_io_desc"))) { + if (!(ctx = talloc_init("sec_io_desc"))) { ret = ADS_ERROR(LDAP_NO_MEMORY); goto ads_set_sd_error; } @@ -1785,7 +1785,7 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads) char *timestr; TALLOC_CTX *ctx; - if (!(ctx = talloc_init())) { + if (!(ctx = talloc_init("ads_server_info"))) { return ADS_ERROR(LDAP_NO_MEMORY); } diff --git a/source3/libads/ldap_user.c b/source3/libads/ldap_user.c index b6fef24b5c..de19e2da5e 100644 --- a/source3/libads/ldap_user.c +++ b/source3/libads/ldap_user.c @@ -50,7 +50,7 @@ ADS_STATUS ads_add_user_acct(ADS_STRUCT *ads, const char *user, if (fullname && *fullname) name = fullname; else name = user; - if (!(ctx = talloc_init_named("ads_add_user_acct"))) + if (!(ctx = talloc_init("ads_add_user_acct"))) return ADS_ERROR(LDAP_NO_MEMORY); status = ADS_ERROR(LDAP_NO_MEMORY); @@ -88,7 +88,7 @@ ADS_STATUS ads_add_group_acct(ADS_STRUCT *ads, const char *group, char *new_dn; const char *objectClass[] = {"top", "group", NULL}; - if (!(ctx = talloc_init_named("ads_add_group_acct"))) + if (!(ctx = talloc_init("ads_add_group_acct"))) return ADS_ERROR(LDAP_NO_MEMORY); status = ADS_ERROR(LDAP_NO_MEMORY); -- cgit From 64501e44ee672936b206ed2d80e13e4c39bbd95c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 30 Dec 2002 23:55:53 +0000 Subject: Catching up with old patches. Add define for VERITAS quota support. Check return in ldap. Jeremy. (This used to be commit 66eff26fc930e37035bba8672f5fd3aeae71078d) --- source3/libads/ldap.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 97ccf76983..1ed1da0b5d 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -326,6 +326,8 @@ static struct berval *dup_berval(TALLOC_CTX *ctx, const struct berval *in_val) if (!in_val) return NULL; value = talloc_zero(ctx, sizeof(struct berval)); + if (value == NULL) + return NULL; if (in_val->bv_len == 0) return value; value->bv_len = in_val->bv_len; -- cgit From 944fb243eb9d28761870f0c86325aaf9665041eb Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 30 Dec 2002 23:55:58 +0000 Subject: Catching up with old patches. Add define for VERITAS quota support. Check return in ldap. Jeremy. (This used to be commit e789edbb287319f52f49f2999917a610565144d9) --- source3/libads/ldap.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 97ccf76983..1ed1da0b5d 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -326,6 +326,8 @@ static struct berval *dup_berval(TALLOC_CTX *ctx, const struct berval *in_val) if (!in_val) return NULL; value = talloc_zero(ctx, sizeof(struct berval)); + if (value == NULL) + return NULL; if (in_val->bv_len == 0) return value; value->bv_len = in_val->bv_len; -- cgit From 6d66fb308ab85bd9691d541764e683e6040cf724 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 2 Jan 2003 09:07:17 +0000 Subject: BIG patch... This patch makes Samba compile cleanly with -Wwrite-strings. - That is, all string literals are marked as 'const'. These strings are always read only, this just marks them as such for passing to other functions. What is most supprising is that I didn't need to change more than a few lines of code (all in 'net', which got a small cleanup of net.h and extern variables). The rest is just adding a lot of 'const'. As far as I can tell, I have not added any new warnings - apart from making all of tdbutil.c's function const (so they warn for adding that const string to struct). Andrew Bartlett (This used to be commit 92a777d0eaa4fb3a1c7835816f93c6bdd456816d) --- source3/libads/disp_sec.c | 6 +++--- source3/libads/ldap.c | 4 ++-- source3/libads/ldap_printer.c | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/disp_sec.c b/source3/libads/disp_sec.c index a7b0bf6f07..c9de447e69 100644 --- a/source3/libads/disp_sec.c +++ b/source3/libads/disp_sec.c @@ -22,7 +22,7 @@ static struct perm_mask_str { uint32 mask; - char *str; + const char *str; } perms[] = { {SEC_RIGHTS_FULL_CTRL, "[Full Control]"}, @@ -83,7 +83,7 @@ static void ads_disp_perms(uint32 type) /* display ACE */ static void ads_disp_ace(SEC_ACE *sec_ace) { - char *access_type = "UNKNOWN"; + const char *access_type = "UNKNOWN"; if (!sec_ace_object(sec_ace->type)) { printf("------- ACE (type: 0x%02x, flags: 0x%02x, size: 0x%02x, mask: 0x%x)\n", @@ -121,7 +121,7 @@ static void ads_disp_ace(SEC_ACE *sec_ace) } /* display ACL */ -static void ads_disp_acl(SEC_ACL *sec_acl, char *type) +static void ads_disp_acl(SEC_ACL *sec_acl, const char *type) { if (!sec_acl) printf("------- (%s) ACL not present\n", type); diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 1ed1da0b5d..1743bc2dd6 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1184,8 +1184,8 @@ static void dump_string(const char *field, char **values) static BOOL ads_dump_field(char *field, void **values, void *data_area) { - struct { - char *name; + const struct { + const char *name; BOOL string; void (*handler)(const char *, struct berval **); } handlers[] = { diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index b2ee5f2265..87ea058896 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -167,7 +167,7 @@ static BOOL map_multi_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods, } struct valmap_to_ads { - char *valname; + const char *valname; BOOL (*fn)(TALLOC_CTX *, ADS_MODLIST *, const REGISTRY_VALUE *); }; @@ -177,7 +177,7 @@ struct valmap_to_ads { static void map_regval_to_ads(TALLOC_CTX *ctx, ADS_MODLIST *mods, REGISTRY_VALUE *value) { - struct valmap_to_ads map[] = { + const struct valmap_to_ads map[] = { {SPOOL_REG_ASSETNUMBER, map_sz}, {SPOOL_REG_BYTESPERMINUTE, map_dword}, {SPOOL_REG_DEFAULTPRIORITY, map_dword}, @@ -250,7 +250,7 @@ static void map_regval_to_ads(TALLOC_CTX *ctx, ADS_MODLIST *mods, WERROR get_remote_printer_publishing_data(struct cli_state *cli, TALLOC_CTX *mem_ctx, ADS_MODLIST *mods, - char *printer) + const char *printer) { WERROR result; char *printername, *servername; -- cgit From 634c54310c92c48dd4eceec602e230a021bdcfc5 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 3 Jan 2003 08:28:12 +0000 Subject: Merge from HEAD - make Samba compile with -Wwrite-strings without additional warnings. (Adds a lot of const). Andrew Bartlett (This used to be commit 3a7458f9472432ef12c43008414925fd1ce8ea0c) --- source3/libads/disp_sec.c | 6 +++--- source3/libads/ldap.c | 4 ++-- source3/libads/ldap_printer.c | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/disp_sec.c b/source3/libads/disp_sec.c index a7b0bf6f07..c9de447e69 100644 --- a/source3/libads/disp_sec.c +++ b/source3/libads/disp_sec.c @@ -22,7 +22,7 @@ static struct perm_mask_str { uint32 mask; - char *str; + const char *str; } perms[] = { {SEC_RIGHTS_FULL_CTRL, "[Full Control]"}, @@ -83,7 +83,7 @@ static void ads_disp_perms(uint32 type) /* display ACE */ static void ads_disp_ace(SEC_ACE *sec_ace) { - char *access_type = "UNKNOWN"; + const char *access_type = "UNKNOWN"; if (!sec_ace_object(sec_ace->type)) { printf("------- ACE (type: 0x%02x, flags: 0x%02x, size: 0x%02x, mask: 0x%x)\n", @@ -121,7 +121,7 @@ static void ads_disp_ace(SEC_ACE *sec_ace) } /* display ACL */ -static void ads_disp_acl(SEC_ACL *sec_acl, char *type) +static void ads_disp_acl(SEC_ACL *sec_acl, const char *type) { if (!sec_acl) printf("------- (%s) ACL not present\n", type); diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 1ed1da0b5d..1743bc2dd6 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1184,8 +1184,8 @@ static void dump_string(const char *field, char **values) static BOOL ads_dump_field(char *field, void **values, void *data_area) { - struct { - char *name; + const struct { + const char *name; BOOL string; void (*handler)(const char *, struct berval **); } handlers[] = { diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index b2ee5f2265..87ea058896 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -167,7 +167,7 @@ static BOOL map_multi_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods, } struct valmap_to_ads { - char *valname; + const char *valname; BOOL (*fn)(TALLOC_CTX *, ADS_MODLIST *, const REGISTRY_VALUE *); }; @@ -177,7 +177,7 @@ struct valmap_to_ads { static void map_regval_to_ads(TALLOC_CTX *ctx, ADS_MODLIST *mods, REGISTRY_VALUE *value) { - struct valmap_to_ads map[] = { + const struct valmap_to_ads map[] = { {SPOOL_REG_ASSETNUMBER, map_sz}, {SPOOL_REG_BYTESPERMINUTE, map_dword}, {SPOOL_REG_DEFAULTPRIORITY, map_dword}, @@ -250,7 +250,7 @@ static void map_regval_to_ads(TALLOC_CTX *ctx, ADS_MODLIST *mods, WERROR get_remote_printer_publishing_data(struct cli_state *cli, TALLOC_CTX *mem_ctx, ADS_MODLIST *mods, - char *printer) + const char *printer) { WERROR result; char *printername, *servername; -- cgit From 22d6569ed514bac025958d6cfdc99ec472a3f5cb Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 11 Jan 2003 03:29:31 +0000 Subject: Patch from Nik Conwell . Don't reference free()ed data when trying to figure out if we have got our ticket yet. Andrew Bartlett (This used to be commit a66ced2cf69145c0a5be5ed91ac306db50c313d1) --- source3/libads/kerberos_verify.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 03917466c6..c1402b1370 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -46,6 +46,7 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, char *password_s; krb5_data password; krb5_enctype *enctypes = NULL; + BOOL auth_ok = False; if (!secrets_init()) { DEBUG(1,("secrets_init failed\n")); @@ -124,11 +125,12 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, if (!(ret = krb5_rd_req(context, &auth_context, &packet, NULL, keytab, NULL, &tkt))) { krb5_free_ktypes(context, enctypes); + auth_ok = True; break; } } - if (!enctypes[i]) { + if (!auth_ok) { DEBUG(3,("krb5_rd_req with auth failed (%s)\n", error_message(ret))); return NT_STATUS_LOGON_FAILURE; -- cgit From 43e4cae106ebc581994dccbf1cc4c9c9559e3e8a Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 15 Jan 2003 16:07:14 +0000 Subject: * removed unused variable from rpcclient code * added container option to net command (patch from SuSE) * Makefile patch for examples/VFS from SuSE (This used to be commit 4a6d8280ea27ca7a6998219aacc4b15b1227a659) --- source3/libads/ldap_user.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap_user.c b/source3/libads/ldap_user.c index de19e2da5e..2e38e7a00d 100644 --- a/source3/libads/ldap_user.c +++ b/source3/libads/ldap_user.c @@ -38,7 +38,7 @@ ADS_STATUS ads_find_user_acct(ADS_STRUCT *ads, void **res, const char *user) } ADS_STATUS ads_add_user_acct(ADS_STRUCT *ads, const char *user, - const char *fullname) + const char *container, const char *fullname) { TALLOC_CTX *ctx; ADS_MODLIST mods; @@ -57,7 +57,7 @@ ADS_STATUS ads_add_user_acct(ADS_STRUCT *ads, const char *user, if (!(upn = talloc_asprintf(ctx, "%s@%s", user, ads->config.realm))) goto done; - if (!(new_dn = talloc_asprintf(ctx, "cn=%s,cn=Users,%s", name, + if (!(new_dn = talloc_asprintf(ctx, "cn=%s,%s,%s", name, container, ads->config.bind_path))) goto done; if (!(controlstr = talloc_asprintf(ctx, "%u", UF_NORMAL_ACCOUNT))) @@ -80,7 +80,7 @@ ADS_STATUS ads_add_user_acct(ADS_STRUCT *ads, const char *user, } ADS_STATUS ads_add_group_acct(ADS_STRUCT *ads, const char *group, - const char *comment) + const char *container, const char *comment) { TALLOC_CTX *ctx; ADS_MODLIST mods; @@ -93,7 +93,7 @@ ADS_STATUS ads_add_group_acct(ADS_STRUCT *ads, const char *group, status = ADS_ERROR(LDAP_NO_MEMORY); - if (!(new_dn = talloc_asprintf(ctx, "cn=%s,cn=Users,%s", group, + if (!(new_dn = talloc_asprintf(ctx, "cn=%s,%s,%s", group, container, ads->config.bind_path))) goto done; if (!(mods = ads_init_mods(ctx))) @@ -102,7 +102,7 @@ ADS_STATUS ads_add_group_acct(ADS_STRUCT *ads, const char *group, ads_mod_str(ctx, &mods, "cn", group); ads_mod_strlist(ctx, &mods, "objectClass",objectClass); ads_mod_str(ctx, &mods, "name", group); - if (comment) + if (comment && *comment) ads_mod_str(ctx, &mods, "description", comment); ads_mod_str(ctx, &mods, "sAMAccountName", group); status = ads_gen_add(ads, new_dn, mods); -- cgit From 9eeab10e54e9e94082ced649b33ee45b4f59f858 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 15 Jan 2003 16:10:57 +0000 Subject: [merge] * removed unused variable from rpcclient code * added container option to net command (patch from SuSE) * Makefile patch for examples/VFS from SuSE (This used to be commit 25a9681ddda47a41fac8fdc97ca50b7f4c579eaf) --- source3/libads/ldap_user.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap_user.c b/source3/libads/ldap_user.c index de19e2da5e..2e38e7a00d 100644 --- a/source3/libads/ldap_user.c +++ b/source3/libads/ldap_user.c @@ -38,7 +38,7 @@ ADS_STATUS ads_find_user_acct(ADS_STRUCT *ads, void **res, const char *user) } ADS_STATUS ads_add_user_acct(ADS_STRUCT *ads, const char *user, - const char *fullname) + const char *container, const char *fullname) { TALLOC_CTX *ctx; ADS_MODLIST mods; @@ -57,7 +57,7 @@ ADS_STATUS ads_add_user_acct(ADS_STRUCT *ads, const char *user, if (!(upn = talloc_asprintf(ctx, "%s@%s", user, ads->config.realm))) goto done; - if (!(new_dn = talloc_asprintf(ctx, "cn=%s,cn=Users,%s", name, + if (!(new_dn = talloc_asprintf(ctx, "cn=%s,%s,%s", name, container, ads->config.bind_path))) goto done; if (!(controlstr = talloc_asprintf(ctx, "%u", UF_NORMAL_ACCOUNT))) @@ -80,7 +80,7 @@ ADS_STATUS ads_add_user_acct(ADS_STRUCT *ads, const char *user, } ADS_STATUS ads_add_group_acct(ADS_STRUCT *ads, const char *group, - const char *comment) + const char *container, const char *comment) { TALLOC_CTX *ctx; ADS_MODLIST mods; @@ -93,7 +93,7 @@ ADS_STATUS ads_add_group_acct(ADS_STRUCT *ads, const char *group, status = ADS_ERROR(LDAP_NO_MEMORY); - if (!(new_dn = talloc_asprintf(ctx, "cn=%s,cn=Users,%s", group, + if (!(new_dn = talloc_asprintf(ctx, "cn=%s,%s,%s", group, container, ads->config.bind_path))) goto done; if (!(mods = ads_init_mods(ctx))) @@ -102,7 +102,7 @@ ADS_STATUS ads_add_group_acct(ADS_STRUCT *ads, const char *group, ads_mod_str(ctx, &mods, "cn", group); ads_mod_strlist(ctx, &mods, "objectClass",objectClass); ads_mod_str(ctx, &mods, "name", group); - if (comment) + if (comment && *comment) ads_mod_str(ctx, &mods, "description", comment); ads_mod_str(ctx, &mods, "sAMAccountName", group); status = ads_gen_add(ads, new_dn, mods); -- cgit From 3b3551985755392970d6bf518ca739b6774915bd Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 21 Jan 2003 01:20:48 +0000 Subject: sanity checks from Ken Cross (This used to be commit ec26877f0b4fbe2c651a6069d22b9ac0637aa2d1) --- source3/libads/ads_struct.c | 4 ++-- source3/libads/ldap.c | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index 3cdd015bf4..c45805cd16 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -94,10 +94,10 @@ ADS_STRUCT *ads_init(const char *realm, /* we need to know if this is a foreign realm to know if we can use lp_ads_server() */ - if (realm && strcasecmp(lp_realm(), realm) != 0) { + if (realm && *realm && strcasecmp(lp_realm(), realm) != 0) { ads->server.foreign = 1; } - if (workgroup && strcasecmp(lp_workgroup(), workgroup) != 0) { + if (workgroup && *workgroup && strcasecmp(lp_workgroup(), workgroup) != 0) { ads->server.foreign = 1; } diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 1743bc2dd6..0a95e019bf 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1429,7 +1429,11 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) if (!ADS_ERR_OK(ret)) return ret; - msg = ads_first_entry(ads, res); + if ( !(msg = ads_first_entry(ads, res) )) { + ret = ADS_ERROR(LDAP_NO_RESULTS_RETURNED); + goto ads_set_sd_error; + } + ads_pull_sid(ads, msg, attrs[1], &sid); if (!(ctx = talloc_init("sec_io_desc"))) { ret = ADS_ERROR(LDAP_NO_MEMORY); -- cgit From 8308ec6979d8d71903cb82963827d194d8c7bff3 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 21 Jan 2003 01:21:33 +0000 Subject: sanity checks from Ken Cross (This used to be commit 9f35846b8e0d711c9101ade9e79394219045383c) --- source3/libads/ads_struct.c | 4 ++-- source3/libads/ldap.c | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index 3cdd015bf4..c45805cd16 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -94,10 +94,10 @@ ADS_STRUCT *ads_init(const char *realm, /* we need to know if this is a foreign realm to know if we can use lp_ads_server() */ - if (realm && strcasecmp(lp_realm(), realm) != 0) { + if (realm && *realm && strcasecmp(lp_realm(), realm) != 0) { ads->server.foreign = 1; } - if (workgroup && strcasecmp(lp_workgroup(), workgroup) != 0) { + if (workgroup && *workgroup && strcasecmp(lp_workgroup(), workgroup) != 0) { ads->server.foreign = 1; } diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 1743bc2dd6..0a95e019bf 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1429,7 +1429,11 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) if (!ADS_ERR_OK(ret)) return ret; - msg = ads_first_entry(ads, res); + if ( !(msg = ads_first_entry(ads, res) )) { + ret = ADS_ERROR(LDAP_NO_RESULTS_RETURNED); + goto ads_set_sd_error; + } + ads_pull_sid(ads, msg, attrs[1], &sid); if (!(ctx = talloc_init("sec_io_desc"))) { ret = ADS_ERROR(LDAP_NO_MEMORY); -- cgit From e97e51f5fd05e533d064ab8dd68a9039f4d44d0c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 21 Jan 2003 06:23:10 +0000 Subject: More fixes getting us closer to full Heimdal compile.... Jeremy. (This used to be commit 193cc4f4fc876c66e97ea6b82bae431d0247c1fa) --- source3/libads/krb5_setpw.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 8079c0953f..73d370d75f 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -141,7 +141,7 @@ static krb5_error_code build_setpw_request(krb5_context context, packet->data = (char *)malloc(ap_req->length + cipherpw.length + 6); /* see the RFC for details */ - p = packet->data + 2; + p = ((char *)packet->data) + 2; RSSVAL(p, 0, 0xff80); p += 2; RSSVAL(p, 0, ap_req->length); p += 2; memcpy(p, ap_req->data, ap_req->length); p += ap_req->length; @@ -172,10 +172,10 @@ static krb5_error_code parse_setpw_reply(krb5_context context, p = packet->data; - if (packet->data[0] == 0x7e || packet->data[0] == 0x5e) { + if (((char *)packet->data)[0] == 0x7e || ((char *)packet->data)[0] == 0x5e) { /* it's an error packet. We should parse it ... */ DEBUG(1,("Got error packet 0x%x from kpasswd server\n", - packet->data[0])); + ((char *)packet->data)[0])); return KRB5KRB_AP_ERR_MODIFIED; } @@ -196,7 +196,7 @@ static krb5_error_code parse_setpw_reply(krb5_context context, ap_rep.length = RSVAL(p, 0); p += 2; - if (p + ap_rep.length >= packet->data + packet->length) { + if (p + ap_rep.length >= (char *)packet->data + packet->length) { DEBUG(1,("ptr beyond end of packet from kpasswd server\n")); return KRB5KRB_AP_ERR_MODIFIED; } @@ -219,7 +219,7 @@ static krb5_error_code parse_setpw_reply(krb5_context context, krb5_free_ap_rep_enc_part(context, ap_rep_enc); cipherresult.data = p; - cipherresult.length = (packet->data + packet->length) - p; + cipherresult.length = ((char *)packet->data + packet->length) - p; ret = krb5_rd_priv(context, auth_context, &cipherresult, &clearresult, &replay); @@ -353,12 +353,8 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char addr_len = sizeof(local_addr); getsockname(sock, &local_addr, &addr_len); - remote_kaddr.addrtype = ADDRTYPE_INET; - remote_kaddr.length = sizeof(((struct sockaddr_in *)&remote_addr)->sin_addr); - remote_kaddr.contents = (char *)&(((struct sockaddr_in *)&remote_addr)->sin_addr); - local_kaddr.addrtype = ADDRTYPE_INET; - local_kaddr.length = sizeof(((struct sockaddr_in *)&local_addr)->sin_addr); - local_kaddr.contents = (char *)&(((struct sockaddr_in *)&local_addr)->sin_addr); + setup_kaddr(&remote_kaddr, &remote_addr); + setup_kaddr(&local_kaddr, &local_addr); ret = krb5_auth_con_setaddrs(context, auth_context, &local_kaddr, NULL); if (ret) { -- cgit From b0aadff2020886cbc2a35bf115e6c359ff28d870 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 21 Jan 2003 06:23:49 +0000 Subject: More fixes getting us closer to full Heimdal compile.... Jeremy. (This used to be commit a7ee6ed64500a0d949849da6996b7dc837518f00) --- source3/libads/krb5_setpw.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 8079c0953f..73d370d75f 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -141,7 +141,7 @@ static krb5_error_code build_setpw_request(krb5_context context, packet->data = (char *)malloc(ap_req->length + cipherpw.length + 6); /* see the RFC for details */ - p = packet->data + 2; + p = ((char *)packet->data) + 2; RSSVAL(p, 0, 0xff80); p += 2; RSSVAL(p, 0, ap_req->length); p += 2; memcpy(p, ap_req->data, ap_req->length); p += ap_req->length; @@ -172,10 +172,10 @@ static krb5_error_code parse_setpw_reply(krb5_context context, p = packet->data; - if (packet->data[0] == 0x7e || packet->data[0] == 0x5e) { + if (((char *)packet->data)[0] == 0x7e || ((char *)packet->data)[0] == 0x5e) { /* it's an error packet. We should parse it ... */ DEBUG(1,("Got error packet 0x%x from kpasswd server\n", - packet->data[0])); + ((char *)packet->data)[0])); return KRB5KRB_AP_ERR_MODIFIED; } @@ -196,7 +196,7 @@ static krb5_error_code parse_setpw_reply(krb5_context context, ap_rep.length = RSVAL(p, 0); p += 2; - if (p + ap_rep.length >= packet->data + packet->length) { + if (p + ap_rep.length >= (char *)packet->data + packet->length) { DEBUG(1,("ptr beyond end of packet from kpasswd server\n")); return KRB5KRB_AP_ERR_MODIFIED; } @@ -219,7 +219,7 @@ static krb5_error_code parse_setpw_reply(krb5_context context, krb5_free_ap_rep_enc_part(context, ap_rep_enc); cipherresult.data = p; - cipherresult.length = (packet->data + packet->length) - p; + cipherresult.length = ((char *)packet->data + packet->length) - p; ret = krb5_rd_priv(context, auth_context, &cipherresult, &clearresult, &replay); @@ -353,12 +353,8 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char addr_len = sizeof(local_addr); getsockname(sock, &local_addr, &addr_len); - remote_kaddr.addrtype = ADDRTYPE_INET; - remote_kaddr.length = sizeof(((struct sockaddr_in *)&remote_addr)->sin_addr); - remote_kaddr.contents = (char *)&(((struct sockaddr_in *)&remote_addr)->sin_addr); - local_kaddr.addrtype = ADDRTYPE_INET; - local_kaddr.length = sizeof(((struct sockaddr_in *)&local_addr)->sin_addr); - local_kaddr.contents = (char *)&(((struct sockaddr_in *)&local_addr)->sin_addr); + setup_kaddr(&remote_kaddr, &remote_addr); + setup_kaddr(&local_kaddr, &local_addr); ret = krb5_auth_con_setaddrs(context, auth_context, &local_kaddr, NULL); if (ret) { -- cgit From e545fe3c0aa1901026d5d11fa48d084e4cecde40 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 21 Jan 2003 20:43:26 +0000 Subject: Get closer to Heimdal compile... Damn. HEAD has different code in kerberos_verify... Jeremy. (This used to be commit e8c4098da619a1429cc4c8251761333a7c0f3458) --- source3/libads/kerberos_verify.c | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index f761467d6f..379525a8e3 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -36,8 +36,6 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, krb5_keytab keytab = NULL; krb5_data packet; krb5_ticket *tkt = NULL; - krb5_data salt; - krb5_encrypt_block eblock; int ret; krb5_keyblock * key; krb5_principal host_princ; @@ -91,24 +89,15 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, return NT_STATUS_LOGON_FAILURE; } - ret = krb5_principal2salt(context, host_princ, &salt); - if (ret) { - DEBUG(1,("krb5_principal2salt failed (%s)\n", error_message(ret))); - return NT_STATUS_LOGON_FAILURE; - } - if (!(key = (krb5_keyblock *)malloc(sizeof(*key)))) { return NT_STATUS_NO_MEMORY; } - krb5_use_enctype(context, &eblock, ENCTYPE_DES_CBC_MD5); - - ret = krb5_string_to_key(context, &eblock, key, &password, &salt); - if (ret) { - DEBUG(1,("krb5_string_to_key failed (%s)\n", error_message(ret))); + if (create_kerberos_key_from_string(context, host_princ, &password, key)) { + SAFE_FREE(key); return NT_STATUS_LOGON_FAILURE; } - + krb5_auth_con_setuseruserkey(context, auth_context, key); packet.length = ticket->length; -- cgit From c79eccad91705526c69ff6bca14060718138c570 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 22 Jan 2003 23:32:33 +0000 Subject: Merge of kerberos changes to make this branch build again! (This used to be commit 51b319f57f28e3993919d7f3db0251a724902332) --- source3/libads/kerberos_verify.c | 53 ++++++++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 13 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 379525a8e3..c1402b1370 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -36,13 +36,17 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, krb5_keytab keytab = NULL; krb5_data packet; krb5_ticket *tkt = NULL; - int ret; + krb5_data salt; + krb5_encrypt_block eblock; + int ret, i; krb5_keyblock * key; krb5_principal host_princ; char *host_princ_s; fstring myname; char *password_s; krb5_data password; + krb5_enctype *enctypes = NULL; + BOOL auth_ok = False; if (!secrets_init()) { DEBUG(1,("secrets_init failed\n")); @@ -67,7 +71,6 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, ret = krb5_set_default_realm(context, ads->auth.realm); if (ret) { DEBUG(1,("krb5_set_default_realm failed (%s)\n", error_message(ret))); - ads_destroy(&ads); return NT_STATUS_LOGON_FAILURE; } @@ -89,31 +92,55 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, return NT_STATUS_LOGON_FAILURE; } + ret = krb5_principal2salt(context, host_princ, &salt); + if (ret) { + DEBUG(1,("krb5_principal2salt failed (%s)\n", error_message(ret))); + return NT_STATUS_LOGON_FAILURE; + } + if (!(key = (krb5_keyblock *)malloc(sizeof(*key)))) { return NT_STATUS_NO_MEMORY; } - if (create_kerberos_key_from_string(context, host_princ, &password, key)) { - SAFE_FREE(key); + if ((ret = krb5_get_permitted_enctypes(context, &enctypes))) { + DEBUG(1,("krb5_get_permitted_enctypes failed (%s)\n", + error_message(ret))); return NT_STATUS_LOGON_FAILURE; } - - krb5_auth_con_setuseruserkey(context, auth_context, key); - packet.length = ticket->length; - packet.data = (krb5_pointer)ticket->data; + /* we need to setup a auth context with each possible encoding type in turn */ + for (i=0;enctypes[i];i++) { + krb5_use_enctype(context, &eblock, enctypes[i]); -#if 0 - file_save("/tmp/ticket.dat", ticket->data, ticket->length); -#endif + ret = krb5_string_to_key(context, &eblock, key, &password, &salt); + if (ret) { + continue; + } - if ((ret = krb5_rd_req(context, &auth_context, &packet, - NULL, keytab, NULL, &tkt))) { + krb5_auth_con_setuseruserkey(context, auth_context, key); + + packet.length = ticket->length; + packet.data = (krb5_pointer)ticket->data; + + if (!(ret = krb5_rd_req(context, &auth_context, &packet, + NULL, keytab, NULL, &tkt))) { + krb5_free_ktypes(context, enctypes); + auth_ok = True; + break; + } + } + + if (!auth_ok) { DEBUG(3,("krb5_rd_req with auth failed (%s)\n", error_message(ret))); return NT_STATUS_LOGON_FAILURE; } +#if 0 + file_save("/tmp/ticket.dat", ticket->data, ticket->length); +#endif + + if (tkt->enc_part2) { *auth_data = data_blob(tkt->enc_part2->authorization_data[0]->contents, tkt->enc_part2->authorization_data[0]->length); -- cgit From 6cf8ac019ec5022455de7ec80e798baf552e291f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 23 Jan 2003 18:15:18 +0000 Subject: Thanks Meeester Potter, for reverting *all* my Heimdal changes because I mistyped a comma :-). Jeremy. (This used to be commit 04cc149c756c396012cfa321a74724b077302b95) --- source3/libads/kerberos_verify.c | 53 ++++++++++------------------------------ 1 file changed, 13 insertions(+), 40 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index c1402b1370..379525a8e3 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -36,17 +36,13 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, krb5_keytab keytab = NULL; krb5_data packet; krb5_ticket *tkt = NULL; - krb5_data salt; - krb5_encrypt_block eblock; - int ret, i; + int ret; krb5_keyblock * key; krb5_principal host_princ; char *host_princ_s; fstring myname; char *password_s; krb5_data password; - krb5_enctype *enctypes = NULL; - BOOL auth_ok = False; if (!secrets_init()) { DEBUG(1,("secrets_init failed\n")); @@ -71,6 +67,7 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, ret = krb5_set_default_realm(context, ads->auth.realm); if (ret) { DEBUG(1,("krb5_set_default_realm failed (%s)\n", error_message(ret))); + ads_destroy(&ads); return NT_STATUS_LOGON_FAILURE; } @@ -92,55 +89,31 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, return NT_STATUS_LOGON_FAILURE; } - ret = krb5_principal2salt(context, host_princ, &salt); - if (ret) { - DEBUG(1,("krb5_principal2salt failed (%s)\n", error_message(ret))); - return NT_STATUS_LOGON_FAILURE; - } - if (!(key = (krb5_keyblock *)malloc(sizeof(*key)))) { return NT_STATUS_NO_MEMORY; } - if ((ret = krb5_get_permitted_enctypes(context, &enctypes))) { - DEBUG(1,("krb5_get_permitted_enctypes failed (%s)\n", - error_message(ret))); + if (create_kerberos_key_from_string(context, host_princ, &password, key)) { + SAFE_FREE(key); return NT_STATUS_LOGON_FAILURE; } + + krb5_auth_con_setuseruserkey(context, auth_context, key); - /* we need to setup a auth context with each possible encoding type in turn */ - for (i=0;enctypes[i];i++) { - krb5_use_enctype(context, &eblock, enctypes[i]); - - ret = krb5_string_to_key(context, &eblock, key, &password, &salt); - if (ret) { - continue; - } - - krb5_auth_con_setuseruserkey(context, auth_context, key); - - packet.length = ticket->length; - packet.data = (krb5_pointer)ticket->data; + packet.length = ticket->length; + packet.data = (krb5_pointer)ticket->data; - if (!(ret = krb5_rd_req(context, &auth_context, &packet, - NULL, keytab, NULL, &tkt))) { - krb5_free_ktypes(context, enctypes); - auth_ok = True; - break; - } - } +#if 0 + file_save("/tmp/ticket.dat", ticket->data, ticket->length); +#endif - if (!auth_ok) { + if ((ret = krb5_rd_req(context, &auth_context, &packet, + NULL, keytab, NULL, &tkt))) { DEBUG(3,("krb5_rd_req with auth failed (%s)\n", error_message(ret))); return NT_STATUS_LOGON_FAILURE; } -#if 0 - file_save("/tmp/ticket.dat", ticket->data, ticket->length); -#endif - - if (tkt->enc_part2) { *auth_data = data_blob(tkt->enc_part2->authorization_data[0]->contents, tkt->enc_part2->authorization_data[0]->length); -- cgit From 755e33ee3f25884096d3fa2ac4bd4cf64a794903 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 28 Jan 2003 00:33:21 +0000 Subject: Get smbd to link with Heimdal. Still missing some client progs... Jeremy. (This used to be commit 85dda434763bbcea260c800599e4b6b73afcf174) --- source3/libads/kerberos_verify.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 379525a8e3..268326fca9 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -114,10 +114,7 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, return NT_STATUS_LOGON_FAILURE; } - if (tkt->enc_part2) { - *auth_data = data_blob(tkt->enc_part2->authorization_data[0]->contents, - tkt->enc_part2->authorization_data[0]->length); - } + get_auth_data_from_tkt(auth_data, tkt); #if 0 if (tkt->enc_part2) { @@ -127,7 +124,7 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, } #endif - if ((ret = krb5_unparse_name(context, tkt->enc_part2->client, principal))) { + if ((ret = krb5_unparse_name(context, get_principal_from_tkt(tkt), principal))) { DEBUG(3,("krb5_unparse_name failed (%s)\n", error_message(ret))); return NT_STATUS_LOGON_FAILURE; -- cgit From cf292aead6bdcced9deac62c50b25e83779d9741 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 30 Jan 2003 04:40:12 +0000 Subject: Sync of Heimdal kerberos stuff with HEAD. If this breaks I'm blaming the dog again. (This used to be commit 6f89ee2c9dc7f03e3dbe7aa734bf67c6a434d135) --- source3/libads/kerberos_verify.c | 60 ++++++++++++++++++++++++++++++---------- 1 file changed, 45 insertions(+), 15 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 268326fca9..c1402b1370 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -36,13 +36,17 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, krb5_keytab keytab = NULL; krb5_data packet; krb5_ticket *tkt = NULL; - int ret; + krb5_data salt; + krb5_encrypt_block eblock; + int ret, i; krb5_keyblock * key; krb5_principal host_princ; char *host_princ_s; fstring myname; char *password_s; krb5_data password; + krb5_enctype *enctypes = NULL; + BOOL auth_ok = False; if (!secrets_init()) { DEBUG(1,("secrets_init failed\n")); @@ -67,7 +71,6 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, ret = krb5_set_default_realm(context, ads->auth.realm); if (ret) { DEBUG(1,("krb5_set_default_realm failed (%s)\n", error_message(ret))); - ads_destroy(&ads); return NT_STATUS_LOGON_FAILURE; } @@ -89,32 +92,59 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, return NT_STATUS_LOGON_FAILURE; } + ret = krb5_principal2salt(context, host_princ, &salt); + if (ret) { + DEBUG(1,("krb5_principal2salt failed (%s)\n", error_message(ret))); + return NT_STATUS_LOGON_FAILURE; + } + if (!(key = (krb5_keyblock *)malloc(sizeof(*key)))) { return NT_STATUS_NO_MEMORY; } - if (create_kerberos_key_from_string(context, host_princ, &password, key)) { - SAFE_FREE(key); + if ((ret = krb5_get_permitted_enctypes(context, &enctypes))) { + DEBUG(1,("krb5_get_permitted_enctypes failed (%s)\n", + error_message(ret))); return NT_STATUS_LOGON_FAILURE; } - - krb5_auth_con_setuseruserkey(context, auth_context, key); - packet.length = ticket->length; - packet.data = (krb5_pointer)ticket->data; + /* we need to setup a auth context with each possible encoding type in turn */ + for (i=0;enctypes[i];i++) { + krb5_use_enctype(context, &eblock, enctypes[i]); -#if 0 - file_save("/tmp/ticket.dat", ticket->data, ticket->length); -#endif + ret = krb5_string_to_key(context, &eblock, key, &password, &salt); + if (ret) { + continue; + } + + krb5_auth_con_setuseruserkey(context, auth_context, key); - if ((ret = krb5_rd_req(context, &auth_context, &packet, - NULL, keytab, NULL, &tkt))) { + packet.length = ticket->length; + packet.data = (krb5_pointer)ticket->data; + + if (!(ret = krb5_rd_req(context, &auth_context, &packet, + NULL, keytab, NULL, &tkt))) { + krb5_free_ktypes(context, enctypes); + auth_ok = True; + break; + } + } + + if (!auth_ok) { DEBUG(3,("krb5_rd_req with auth failed (%s)\n", error_message(ret))); return NT_STATUS_LOGON_FAILURE; } - get_auth_data_from_tkt(auth_data, tkt); +#if 0 + file_save("/tmp/ticket.dat", ticket->data, ticket->length); +#endif + + + if (tkt->enc_part2) { + *auth_data = data_blob(tkt->enc_part2->authorization_data[0]->contents, + tkt->enc_part2->authorization_data[0]->length); + } #if 0 if (tkt->enc_part2) { @@ -124,7 +154,7 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, } #endif - if ((ret = krb5_unparse_name(context, get_principal_from_tkt(tkt), principal))) { + if ((ret = krb5_unparse_name(context, tkt->enc_part2->client, principal))) { DEBUG(3,("krb5_unparse_name failed (%s)\n", error_message(ret))); return NT_STATUS_LOGON_FAILURE; -- cgit From 32bfb31947af7f0a98ce58b317c79d979a753327 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 30 Jan 2003 18:03:34 +0000 Subject: Revert tpot's HEAD merge which broke the Heimdal build. Jeremy. (This used to be commit 1298ecd0b8a3a9e0a2de42d0c049856cad65e272) --- source3/libads/kerberos_verify.c | 60 ++++++++++------------------------------ 1 file changed, 15 insertions(+), 45 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index c1402b1370..268326fca9 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -36,17 +36,13 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, krb5_keytab keytab = NULL; krb5_data packet; krb5_ticket *tkt = NULL; - krb5_data salt; - krb5_encrypt_block eblock; - int ret, i; + int ret; krb5_keyblock * key; krb5_principal host_princ; char *host_princ_s; fstring myname; char *password_s; krb5_data password; - krb5_enctype *enctypes = NULL; - BOOL auth_ok = False; if (!secrets_init()) { DEBUG(1,("secrets_init failed\n")); @@ -71,6 +67,7 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, ret = krb5_set_default_realm(context, ads->auth.realm); if (ret) { DEBUG(1,("krb5_set_default_realm failed (%s)\n", error_message(ret))); + ads_destroy(&ads); return NT_STATUS_LOGON_FAILURE; } @@ -92,59 +89,32 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, return NT_STATUS_LOGON_FAILURE; } - ret = krb5_principal2salt(context, host_princ, &salt); - if (ret) { - DEBUG(1,("krb5_principal2salt failed (%s)\n", error_message(ret))); - return NT_STATUS_LOGON_FAILURE; - } - if (!(key = (krb5_keyblock *)malloc(sizeof(*key)))) { return NT_STATUS_NO_MEMORY; } - if ((ret = krb5_get_permitted_enctypes(context, &enctypes))) { - DEBUG(1,("krb5_get_permitted_enctypes failed (%s)\n", - error_message(ret))); + if (create_kerberos_key_from_string(context, host_princ, &password, key)) { + SAFE_FREE(key); return NT_STATUS_LOGON_FAILURE; } + + krb5_auth_con_setuseruserkey(context, auth_context, key); - /* we need to setup a auth context with each possible encoding type in turn */ - for (i=0;enctypes[i];i++) { - krb5_use_enctype(context, &eblock, enctypes[i]); - - ret = krb5_string_to_key(context, &eblock, key, &password, &salt); - if (ret) { - continue; - } - - krb5_auth_con_setuseruserkey(context, auth_context, key); - - packet.length = ticket->length; - packet.data = (krb5_pointer)ticket->data; + packet.length = ticket->length; + packet.data = (krb5_pointer)ticket->data; - if (!(ret = krb5_rd_req(context, &auth_context, &packet, - NULL, keytab, NULL, &tkt))) { - krb5_free_ktypes(context, enctypes); - auth_ok = True; - break; - } - } +#if 0 + file_save("/tmp/ticket.dat", ticket->data, ticket->length); +#endif - if (!auth_ok) { + if ((ret = krb5_rd_req(context, &auth_context, &packet, + NULL, keytab, NULL, &tkt))) { DEBUG(3,("krb5_rd_req with auth failed (%s)\n", error_message(ret))); return NT_STATUS_LOGON_FAILURE; } -#if 0 - file_save("/tmp/ticket.dat", ticket->data, ticket->length); -#endif - - - if (tkt->enc_part2) { - *auth_data = data_blob(tkt->enc_part2->authorization_data[0]->contents, - tkt->enc_part2->authorization_data[0]->length); - } + get_auth_data_from_tkt(auth_data, tkt); #if 0 if (tkt->enc_part2) { @@ -154,7 +124,7 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, } #endif - if ((ret = krb5_unparse_name(context, tkt->enc_part2->client, principal))) { + if ((ret = krb5_unparse_name(context, get_principal_from_tkt(tkt), principal))) { DEBUG(3,("krb5_unparse_name failed (%s)\n", error_message(ret))); return NT_STATUS_LOGON_FAILURE; -- cgit From c2b134cc3b67d48961226cbfac6ea3a2fc7cc1a6 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 1 Feb 2003 05:20:11 +0000 Subject: Always escape ldap filter strings. Escaping code was from pam_ldap, but I'm to blame for the realloc() stuff. Plus a couple of minor updates to libads. Andrew Bartlett (This used to be commit 34b2e558a4b3cfd753339bb228a9799e27ed8170) --- source3/libads/ads_ldap.c | 12 +++++++++++- source3/libads/ldap.c | 28 +++++++++++++++++++++------- source3/libads/ldap_user.c | 9 +++++++-- 3 files changed, 39 insertions(+), 10 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_ldap.c b/source3/libads/ads_ldap.c index 05b016539e..97f12de0f7 100644 --- a/source3/libads/ads_ldap.c +++ b/source3/libads/ads_ldap.c @@ -37,9 +37,16 @@ NTSTATUS ads_name_to_sid(ADS_STRUCT *ads, char *exp; uint32 t; NTSTATUS status = NT_STATUS_UNSUCCESSFUL; + char *escaped_name = escape_ldap_string_alloc(name); + char *escaped_realm = escape_ldap_string_alloc(ads->config.realm); + + if (!escaped_name || !escaped_realm) { + status = NT_STATUS_NO_MEMORY; + goto done; + } if (asprintf(&exp, "(|(sAMAccountName=%s)(userPrincipalName=%s@%s))", - name, name, ads->config.realm) == -1) { + escaped_name, escaped_name, escaped_realm) == -1) { DEBUG(1,("ads_name_to_sid: asprintf failed!\n")); status = NT_STATUS_NO_MEMORY; goto done; @@ -77,6 +84,9 @@ NTSTATUS ads_name_to_sid(ADS_STRUCT *ads, done: if (res) ads_msgfree(ads, res); + SAFE_FREE(escaped_name); + SAFE_FREE(escaped_realm); + return status; } diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 0a95e019bf..603f17c994 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -974,7 +974,7 @@ ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ADS_MODLIST mods) /* make sure the end of the list is NULL */ mods[i] = NULL; - ret = ldap_add_s(ads->ld, utf8_dn ? utf8_dn : new_dn, mods); + ret = ldap_add_s(ads->ld, utf8_dn, mods); SAFE_FREE(utf8_dn); return ADS_ERROR(ret); } @@ -994,7 +994,7 @@ ADS_STATUS ads_del_dn(ADS_STRUCT *ads, char *del_dn) return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); } - ret = ldap_delete(ads->ld, utf8_dn ? utf8_dn : del_dn); + ret = ldap_delete(ads->ld, utf8_dn); return ADS_ERROR(ret); } @@ -1029,8 +1029,8 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, ADS_MODLIST mods; const char *objectClass[] = {"top", "person", "organizationalPerson", "user", "computer", NULL}; - const char *servicePrincipalName[3] = {NULL, NULL, NULL}; - char *psp; + const char *servicePrincipalName[5] = {NULL, NULL, NULL, NULL, NULL}; + char *psp, *psp2; unsigned acct_control; if (!(ctx = talloc_init("machine_account"))) @@ -1051,10 +1051,16 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, ads->config.bind_path); servicePrincipalName[0] = talloc_asprintf(ctx, "HOST/%s", hostname); psp = talloc_asprintf(ctx, "HOST/%s.%s", - hostname, - ads->config.realm); + hostname, + ads->config.realm); strlower(&psp[5]); servicePrincipalName[1] = psp; + servicePrincipalName[2] = talloc_asprintf(ctx, "CIFS/%s", hostname); + psp2 = talloc_asprintf(ctx, "CIFS/%s.%s", + hostname, + ads->config.realm); + strlower(&psp2[5]); + servicePrincipalName[3] = psp2; free(ou_str); if (!new_dn) @@ -1405,6 +1411,7 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) size_t sd_size = 0; struct berval bval = {0, NULL}; prs_struct ps_wire; + char *escaped_hostname = escape_ldap_string_alloc(hostname); LDAPMessage *res = 0; LDAPMessage *msg = 0; @@ -1420,11 +1427,18 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) ret = ADS_ERROR(LDAP_SUCCESS); - if (asprintf(&exp, "(samAccountName=%s$)", hostname) == -1) { + if (!escaped_hostname) { + return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + } + + if (asprintf(&exp, "(samAccountName=%s$)", escaped_hostname) == -1) { DEBUG(1, ("ads_set_machine_sd: asprintf failed!\n")); + SAFE_FREE(escaped_hostname); return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); } + SAFE_FREE(escaped_hostname); + ret = ads_search(ads, (void *) &res, exp, attrs); if (!ADS_ERR_OK(ret)) return ret; diff --git a/source3/libads/ldap_user.c b/source3/libads/ldap_user.c index 2e38e7a00d..7efe5338f3 100644 --- a/source3/libads/ldap_user.c +++ b/source3/libads/ldap_user.c @@ -30,10 +30,15 @@ ADS_STATUS ads_find_user_acct(ADS_STRUCT *ads, void **res, const char *user) ADS_STATUS status; char *exp; const char *attrs[] = {"*", NULL}; + char *escaped_user = escape_ldap_string_alloc(user); + if (!escaped_user) { + return ADS_ERROR(LDAP_NO_MEMORY); + } - asprintf(&exp, "(samAccountName=%s)", user); + asprintf(&exp, "(samAccountName=%s)", escaped_user); status = ads_search(ads, res, exp, attrs); - free(exp); + SAFE_FREE(exp); + SAFE_FREE(escaped_user); return status; } -- cgit From 963e88aa90853a7e45c72cbc6630aa705b6d4e55 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 1 Feb 2003 07:59:29 +0000 Subject: Merge LDAP filter parinoia from HEAD, a few other pdb_ldap updates and some misc libads fixes. Andrew Bartlett (This used to be commit 9c3a1710efba9fa4160004a554687d4b85927bb1) --- source3/libads/ldap.c | 28 +++++++++++++++++++++------- source3/libads/ldap_user.c | 9 +++++++-- 2 files changed, 28 insertions(+), 9 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 0a95e019bf..603f17c994 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -974,7 +974,7 @@ ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ADS_MODLIST mods) /* make sure the end of the list is NULL */ mods[i] = NULL; - ret = ldap_add_s(ads->ld, utf8_dn ? utf8_dn : new_dn, mods); + ret = ldap_add_s(ads->ld, utf8_dn, mods); SAFE_FREE(utf8_dn); return ADS_ERROR(ret); } @@ -994,7 +994,7 @@ ADS_STATUS ads_del_dn(ADS_STRUCT *ads, char *del_dn) return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); } - ret = ldap_delete(ads->ld, utf8_dn ? utf8_dn : del_dn); + ret = ldap_delete(ads->ld, utf8_dn); return ADS_ERROR(ret); } @@ -1029,8 +1029,8 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, ADS_MODLIST mods; const char *objectClass[] = {"top", "person", "organizationalPerson", "user", "computer", NULL}; - const char *servicePrincipalName[3] = {NULL, NULL, NULL}; - char *psp; + const char *servicePrincipalName[5] = {NULL, NULL, NULL, NULL, NULL}; + char *psp, *psp2; unsigned acct_control; if (!(ctx = talloc_init("machine_account"))) @@ -1051,10 +1051,16 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, ads->config.bind_path); servicePrincipalName[0] = talloc_asprintf(ctx, "HOST/%s", hostname); psp = talloc_asprintf(ctx, "HOST/%s.%s", - hostname, - ads->config.realm); + hostname, + ads->config.realm); strlower(&psp[5]); servicePrincipalName[1] = psp; + servicePrincipalName[2] = talloc_asprintf(ctx, "CIFS/%s", hostname); + psp2 = talloc_asprintf(ctx, "CIFS/%s.%s", + hostname, + ads->config.realm); + strlower(&psp2[5]); + servicePrincipalName[3] = psp2; free(ou_str); if (!new_dn) @@ -1405,6 +1411,7 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) size_t sd_size = 0; struct berval bval = {0, NULL}; prs_struct ps_wire; + char *escaped_hostname = escape_ldap_string_alloc(hostname); LDAPMessage *res = 0; LDAPMessage *msg = 0; @@ -1420,11 +1427,18 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) ret = ADS_ERROR(LDAP_SUCCESS); - if (asprintf(&exp, "(samAccountName=%s$)", hostname) == -1) { + if (!escaped_hostname) { + return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + } + + if (asprintf(&exp, "(samAccountName=%s$)", escaped_hostname) == -1) { DEBUG(1, ("ads_set_machine_sd: asprintf failed!\n")); + SAFE_FREE(escaped_hostname); return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); } + SAFE_FREE(escaped_hostname); + ret = ads_search(ads, (void *) &res, exp, attrs); if (!ADS_ERR_OK(ret)) return ret; diff --git a/source3/libads/ldap_user.c b/source3/libads/ldap_user.c index 2e38e7a00d..7efe5338f3 100644 --- a/source3/libads/ldap_user.c +++ b/source3/libads/ldap_user.c @@ -30,10 +30,15 @@ ADS_STATUS ads_find_user_acct(ADS_STRUCT *ads, void **res, const char *user) ADS_STATUS status; char *exp; const char *attrs[] = {"*", NULL}; + char *escaped_user = escape_ldap_string_alloc(user); + if (!escaped_user) { + return ADS_ERROR(LDAP_NO_MEMORY); + } - asprintf(&exp, "(samAccountName=%s)", user); + asprintf(&exp, "(samAccountName=%s)", escaped_user); status = ads_search(ads, res, exp, attrs); - free(exp); + SAFE_FREE(exp); + SAFE_FREE(escaped_user); return status; } -- cgit From 0701e642f2d78ff572f7d7dcdf9b5c59750c6c30 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 4 Feb 2003 23:44:05 +0000 Subject: Mem alloc failure checks. Jeremy. (This used to be commit 4e33e3f37fd548b9b1ed3c84f673a853b0dc4818) --- source3/libads/ads_struct.c | 18 ++++++++++-------- source3/libads/krb5_setpw.c | 25 +++++++++++++++++++++---- source3/libads/ldap.c | 39 ++++++++++++++++++++++++++++----------- 3 files changed, 59 insertions(+), 23 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index c45805cd16..652bfe31be 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -33,32 +33,34 @@ char *ads_build_path(const char *realm, const char *sep, const char *field, int r = strdup(realm); - if (!r || !*r) return r; + if (!r || !*r) + return r; - for (p=r; *p; p++) { - if (strchr(sep, *p)) numbits++; - } + for (p=r; *p; p++) + if (strchr(sep, *p)) + numbits++; len = (numbits+1)*(strlen(field)+1) + strlen(r) + 1; ret = malloc(len); + if (!ret) + return NULL; + strlcpy(ret,field, len); p=strtok(r,sep); strlcat(ret, p, len); while ((p=strtok(NULL,sep))) { char *s; - if (reverse) { + if (reverse) asprintf(&s, "%s%s,%s", field, p, ret); - } else { + else asprintf(&s, "%s,%s%s", ret, field, p); - } free(ret); ret = s; } free(r); - return ret; } diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 73d370d75f..087b0e9a71 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -139,13 +139,19 @@ static krb5_error_code build_setpw_request(krb5_context context, } packet->data = (char *)malloc(ap_req->length + cipherpw.length + 6); + if (!packet->data) + return -1; /* see the RFC for details */ p = ((char *)packet->data) + 2; - RSSVAL(p, 0, 0xff80); p += 2; - RSSVAL(p, 0, ap_req->length); p += 2; - memcpy(p, ap_req->data, ap_req->length); p += ap_req->length; - memcpy(p, cipherpw.data, cipherpw.length); p += cipherpw.length; + RSSVAL(p, 0, 0xff80); + p += 2; + RSSVAL(p, 0, ap_req->length); + p += 2; + memcpy(p, ap_req->data, ap_req->length); + p += ap_req->length; + memcpy(p, cipherpw.data, cipherpw.length); + p += cipherpw.length; packet->length = PTR_DIFF(p,packet->data); RSSVAL(packet->data, 0, packet->length); @@ -397,6 +403,17 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char chpw_rep.length = 1500; chpw_rep.data = (char *) malloc(chpw_rep.length); + if (!chpw_rep.data) { + close(sock); + free(ap_req.data); + krb5_free_creds(context, credsp); + krb5_free_principal(context, creds.client); + krb5_free_principal(context, principal); + krb5_free_context(context); + DEBUG(1,("send of chpw failed (%s)\n", strerror(errno))); + errno = ENOMEM; + return ADS_ERROR_SYSTEM(errno); + } ret = read(sock, chpw_rep.data, chpw_rep.length); if (ret < 0) { diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 603f17c994..41e70fbcae 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1528,7 +1528,8 @@ char *ads_pull_string(ADS_STRUCT *ads, int rc; values = ldap_get_values(ads->ld, msg, field); - if (!values) return NULL; + if (!values) + return NULL; if (values[0]) { rc = pull_utf8_talloc(mem_ctx, &ux_string, @@ -1557,15 +1558,22 @@ char **ads_pull_strings(ADS_STRUCT *ads, int i, n; values = ldap_get_values(ads->ld, msg, field); - if (!values) return NULL; + if (!values) + return NULL; - for (i=0;values[i];i++) /* noop */ ; + for (i=0;values[i];i++) + /* noop */ ; n = i; ret = talloc(mem_ctx, sizeof(char *) * (n+1)); + if (!ret) { + ldap_value_free(values); + return NULL; + } for (i=0;ild, msg, field); - if (!values) return False; + if (!values) + return False; if (!values[0]) { ldap_value_free(values); return False; @@ -1614,7 +1623,8 @@ BOOL ads_pull_guid(ADS_STRUCT *ads, char **values; values = ldap_get_values(ads->ld, msg, "objectGUID"); - if (!values) return False; + if (!values) + return False; if (values[0]) { memcpy(guid, values[0], sizeof(GUID)); @@ -1643,11 +1653,11 @@ BOOL ads_pull_sid(ADS_STRUCT *ads, values = ldap_get_values_len(ads->ld, msg, field); - if (!values) return False; + if (!values) + return False; - if (values[0]) { + if (values[0]) ret = sid_parse(values[0]->bv_val, values[0]->bv_len, sid); - } ldap_value_free_len(values); return ret; @@ -1671,16 +1681,23 @@ int ads_pull_sids(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, values = ldap_get_values_len(ads->ld, msg, field); - if (!values) return 0; + if (!values) + return 0; - for (i=0; values[i]; i++) /* nop */ ; + for (i=0; values[i]; i++) + /* nop */ ; (*sids) = talloc(mem_ctx, sizeof(DOM_SID) * i); + if (!(*sids)) { + ldap_value_free_len(values); + return 0; + } count = 0; for (i=0; values[i]; i++) { ret = sid_parse(values[i]->bv_val, values[i]->bv_len, &(*sids)[count]); - if (ret) count++; + if (ret) + count++; } ldap_value_free_len(values); -- cgit From eccae5d23a5a4e2ee63891196d27cc4938019893 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 4 Feb 2003 23:44:28 +0000 Subject: Mem alloc checks. Jeremy. (This used to be commit 46ea028169426fbcad92d3d5bf786e88be8f5112) --- source3/libads/ads_struct.c | 18 ++++++++++-------- source3/libads/krb5_setpw.c | 25 +++++++++++++++++++++---- source3/libads/ldap.c | 39 ++++++++++++++++++++++++++++----------- 3 files changed, 59 insertions(+), 23 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index c45805cd16..652bfe31be 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -33,32 +33,34 @@ char *ads_build_path(const char *realm, const char *sep, const char *field, int r = strdup(realm); - if (!r || !*r) return r; + if (!r || !*r) + return r; - for (p=r; *p; p++) { - if (strchr(sep, *p)) numbits++; - } + for (p=r; *p; p++) + if (strchr(sep, *p)) + numbits++; len = (numbits+1)*(strlen(field)+1) + strlen(r) + 1; ret = malloc(len); + if (!ret) + return NULL; + strlcpy(ret,field, len); p=strtok(r,sep); strlcat(ret, p, len); while ((p=strtok(NULL,sep))) { char *s; - if (reverse) { + if (reverse) asprintf(&s, "%s%s,%s", field, p, ret); - } else { + else asprintf(&s, "%s,%s%s", ret, field, p); - } free(ret); ret = s; } free(r); - return ret; } diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 73d370d75f..087b0e9a71 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -139,13 +139,19 @@ static krb5_error_code build_setpw_request(krb5_context context, } packet->data = (char *)malloc(ap_req->length + cipherpw.length + 6); + if (!packet->data) + return -1; /* see the RFC for details */ p = ((char *)packet->data) + 2; - RSSVAL(p, 0, 0xff80); p += 2; - RSSVAL(p, 0, ap_req->length); p += 2; - memcpy(p, ap_req->data, ap_req->length); p += ap_req->length; - memcpy(p, cipherpw.data, cipherpw.length); p += cipherpw.length; + RSSVAL(p, 0, 0xff80); + p += 2; + RSSVAL(p, 0, ap_req->length); + p += 2; + memcpy(p, ap_req->data, ap_req->length); + p += ap_req->length; + memcpy(p, cipherpw.data, cipherpw.length); + p += cipherpw.length; packet->length = PTR_DIFF(p,packet->data); RSSVAL(packet->data, 0, packet->length); @@ -397,6 +403,17 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char chpw_rep.length = 1500; chpw_rep.data = (char *) malloc(chpw_rep.length); + if (!chpw_rep.data) { + close(sock); + free(ap_req.data); + krb5_free_creds(context, credsp); + krb5_free_principal(context, creds.client); + krb5_free_principal(context, principal); + krb5_free_context(context); + DEBUG(1,("send of chpw failed (%s)\n", strerror(errno))); + errno = ENOMEM; + return ADS_ERROR_SYSTEM(errno); + } ret = read(sock, chpw_rep.data, chpw_rep.length); if (ret < 0) { diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 603f17c994..41e70fbcae 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1528,7 +1528,8 @@ char *ads_pull_string(ADS_STRUCT *ads, int rc; values = ldap_get_values(ads->ld, msg, field); - if (!values) return NULL; + if (!values) + return NULL; if (values[0]) { rc = pull_utf8_talloc(mem_ctx, &ux_string, @@ -1557,15 +1558,22 @@ char **ads_pull_strings(ADS_STRUCT *ads, int i, n; values = ldap_get_values(ads->ld, msg, field); - if (!values) return NULL; + if (!values) + return NULL; - for (i=0;values[i];i++) /* noop */ ; + for (i=0;values[i];i++) + /* noop */ ; n = i; ret = talloc(mem_ctx, sizeof(char *) * (n+1)); + if (!ret) { + ldap_value_free(values); + return NULL; + } for (i=0;ild, msg, field); - if (!values) return False; + if (!values) + return False; if (!values[0]) { ldap_value_free(values); return False; @@ -1614,7 +1623,8 @@ BOOL ads_pull_guid(ADS_STRUCT *ads, char **values; values = ldap_get_values(ads->ld, msg, "objectGUID"); - if (!values) return False; + if (!values) + return False; if (values[0]) { memcpy(guid, values[0], sizeof(GUID)); @@ -1643,11 +1653,11 @@ BOOL ads_pull_sid(ADS_STRUCT *ads, values = ldap_get_values_len(ads->ld, msg, field); - if (!values) return False; + if (!values) + return False; - if (values[0]) { + if (values[0]) ret = sid_parse(values[0]->bv_val, values[0]->bv_len, sid); - } ldap_value_free_len(values); return ret; @@ -1671,16 +1681,23 @@ int ads_pull_sids(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, values = ldap_get_values_len(ads->ld, msg, field); - if (!values) return 0; + if (!values) + return 0; - for (i=0; values[i]; i++) /* nop */ ; + for (i=0; values[i]; i++) + /* nop */ ; (*sids) = talloc(mem_ctx, sizeof(DOM_SID) * i); + if (!(*sids)) { + ldap_value_free_len(values); + return 0; + } count = 0; for (i=0; values[i]; i++) { ret = sid_parse(values[i]->bv_val, values[i]->bv_len, &(*sids)[count]); - if (ret) count++; + if (ret) + count++; } ldap_value_free_len(values); -- cgit From 3b562efcbd00730c4999aec9950216ef73a34e2b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 12 Feb 2003 00:40:41 +0000 Subject: add a note about a better method for finding netbios name of workgroup (not implemented yet) (This used to be commit 8a8cca78adebba640c6ce971d8888515bf0ea4be) --- source3/libads/ldap.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 41e70fbcae..867d124273 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1981,6 +1981,13 @@ ADS_STATUS ads_domain_sid(ADS_STRUCT *ads, DOM_SID *sid) for the domain, but there isn't a simple query to do this. Instead we look for the principle names on the DCs account and find one that has the right form, then extract the netbios name of the domain from that + + NOTE! better method is this: + +bin/net -Uadministrator%XXXXX ads search '(&(objectclass=crossref)(dnsroot=VNET3.HOME.SAMBA.ORG))' nETBIOSName + +but you need to force the bind path to match the configurationNamingContext from the rootDSE + */ ADS_STATUS ads_workgroup_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char **workgroup) { -- cgit From abbbaa2f6f9f05164cf146ea3c712ea5a57afaa9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 12 Feb 2003 01:07:48 +0000 Subject: Merging from HEAD - add a note about a better method for finding netbios name of workgroup (not implemented yet) Jeremy. (This used to be commit c0eab99753032f5f49bc7adeb1ff95eceb6fe0fe) --- source3/libads/ldap.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 41e70fbcae..867d124273 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1981,6 +1981,13 @@ ADS_STATUS ads_domain_sid(ADS_STRUCT *ads, DOM_SID *sid) for the domain, but there isn't a simple query to do this. Instead we look for the principle names on the DCs account and find one that has the right form, then extract the netbios name of the domain from that + + NOTE! better method is this: + +bin/net -Uadministrator%XXXXX ads search '(&(objectclass=crossref)(dnsroot=VNET3.HOME.SAMBA.ORG))' nETBIOSName + +but you need to force the bind path to match the configurationNamingContext from the rootDSE + */ ADS_STATUS ads_workgroup_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char **workgroup) { -- cgit From 8fc1f1aead6db996a6d96efdc5f81779afc9c8d2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 14 Feb 2003 22:55:46 +0000 Subject: Ensure that only parse_prs.c access internal members of the prs_struct. Needed to move to disk based i/o later. Jeremy. (This used to be commit a823fee5b41a5b6cd4ef05aa1f85f7725bd272a5) --- source3/libads/ldap.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 867d124273..47a94f0a08 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1157,8 +1157,8 @@ static void dump_sd(const char *filed, struct berval **values) /* prepare data */ prs_init(&ps, values[0]->bv_len, ctx, UNMARSHALL); - prs_append_data(&ps, values[0]->bv_val, values[0]->bv_len); - ps.data_offset = 0; + prs_copy_data_in(&ps, values[0]->bv_val, values[0]->bv_len); + prs_set_offset(&ps,0); /* parse secdesc */ if (!sec_io_desc("sd", &psd, &ps, 1)) { @@ -1478,7 +1478,13 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) if (!(mods = ads_init_mods(ctx))) return ADS_ERROR(LDAP_NO_MEMORY); bval.bv_len = sd_size; - bval.bv_val = prs_data_p(&ps_wire); + bval.bv_val = talloc(ctx, sd_size); + if (!bval.bv_val) { + ret = ADS_ERROR(LDAP_NO_MEMORY); + goto ads_set_sd_error; + } + prs_copy_all_data_out((char *)&bval.bv_val, &ps_wire); + ads_mod_ber(ctx, &mods, attrs[0], &bval); ret = ads_gen_mod(ads, dn, mods); @@ -1726,8 +1732,8 @@ BOOL ads_pull_sd(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, if (values[0]) { prs_init(&ps, values[0]->bv_len, mem_ctx, UNMARSHALL); - prs_append_data(&ps, values[0]->bv_val, values[0]->bv_len); - ps.data_offset = 0; + prs_copy_data_in(&ps, values[0]->bv_val, values[0]->bv_len); + prs_set_offset(&ps,0); ret = sec_io_desc("sd", sd, &ps, 1); } -- cgit From 4cd6e31bd364270580f2907fbc5669bf29d09578 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 14 Feb 2003 23:04:03 +0000 Subject: Ensure that only parse_prs.c access internal members of the prs_struct. Needed to move to disk based i/o later. Jeremy. (This used to be commit 4c3ee228fcdb089eaeead95e79532a9cf6cb0de6) --- source3/libads/ldap.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 867d124273..47a94f0a08 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1157,8 +1157,8 @@ static void dump_sd(const char *filed, struct berval **values) /* prepare data */ prs_init(&ps, values[0]->bv_len, ctx, UNMARSHALL); - prs_append_data(&ps, values[0]->bv_val, values[0]->bv_len); - ps.data_offset = 0; + prs_copy_data_in(&ps, values[0]->bv_val, values[0]->bv_len); + prs_set_offset(&ps,0); /* parse secdesc */ if (!sec_io_desc("sd", &psd, &ps, 1)) { @@ -1478,7 +1478,13 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) if (!(mods = ads_init_mods(ctx))) return ADS_ERROR(LDAP_NO_MEMORY); bval.bv_len = sd_size; - bval.bv_val = prs_data_p(&ps_wire); + bval.bv_val = talloc(ctx, sd_size); + if (!bval.bv_val) { + ret = ADS_ERROR(LDAP_NO_MEMORY); + goto ads_set_sd_error; + } + prs_copy_all_data_out((char *)&bval.bv_val, &ps_wire); + ads_mod_ber(ctx, &mods, attrs[0], &bval); ret = ads_gen_mod(ads, dn, mods); @@ -1726,8 +1732,8 @@ BOOL ads_pull_sd(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, if (values[0]) { prs_init(&ps, values[0]->bv_len, mem_ctx, UNMARSHALL); - prs_append_data(&ps, values[0]->bv_val, values[0]->bv_len); - ps.data_offset = 0; + prs_copy_data_in(&ps, values[0]->bv_val, values[0]->bv_len); + prs_set_offset(&ps,0); ret = sec_io_desc("sd", sd, &ps, 1); } -- cgit From e4202a9fe70785a0a5b47c90df696a880294d310 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 15 Feb 2003 00:29:21 +0000 Subject: Antti Andreimann has done some changes to enable users w/o full administrative access on computer accounts to join a computer into AD domain. The patch and detailed changelog is available at: http://www.itcollege.ee/~aandreim/samba This is a list of changes in general: 1. When creating machine account do not fail if SD cannot be changed. setting SD is not mandatory and join will work perfectly without it. 2. Implement KPASSWD CHANGEPW protocol for changing trust password so machine account does not need to have reset password right for itself. 3. Command line utilities no longer interfere with user's existing kerberos ticket cache. 4. Command line utilities can do kerberos authentication even if username is specified (-U). Initial TGT will be requested in this case. I've modified the patch to share the kinit code, rather than copying it, and updated it to current CVS. The other change included in the original patch (local realms) has been left out for now. Andrew Bartlett (This used to be commit ce52f1c2ed4d3ddafe8ae6258c90b90fa434fe43) --- source3/libads/krb5_setpw.c | 428 +++++++++++++++++++++++++++++++------------- source3/libads/ldap.c | 24 ++- source3/libads/sasl.c | 7 +- source3/libads/util.c | 10 +- 4 files changed, 337 insertions(+), 132 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 087b0e9a71..c3ec754e39 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -24,13 +24,23 @@ #ifdef HAVE_KRB5 #define DEFAULT_KPASSWD_PORT 464 -#define KRB5_KPASSWD_VERS_CHANGEPW 1 -#define KRB5_KPASSWD_VERS_SETPW 0xff80 -#define KRB5_KPASSWD_ACCESSDENIED 5 -#define KRB5_KPASSWD_BAD_VERSION 6 - -/* This implements the Kerb password change protocol as specifed in - * kerb-chg-password-02.txt +#define KRB5_KPASSWD_VERS_CHANGEPW 1 +#define KRB5_KPASSWD_VERS_SETPW 2 +#define KRB5_KPASSWD_VERS_SETPW_MS 0xff80 +#define KRB5_KPASSWD_ACCESSDENIED 5 +#define KRB5_KPASSWD_BAD_VERSION 6 +#define KRB5_KPASSWD_INITIAL_FLAG_NEEDED 7 + +/* Those are defined by kerberos-set-passwd-02.txt and are probably + * not supported by M$ implementation */ +#define KRB5_KPASSWD_POLICY_REJECT 8 +#define KRB5_KPASSWD_BAD_PRINCIPAL 9 +#define KRB5_KPASSWD_ETYPE_NOSUPP 10 + +/* This implements kerberos password change protocol as specified in + * kerb-chg-password-02.txt and kerberos-set-passwd-02.txt + * as well as microsoft version of the protocol + * as specified in kerberos-set-passwd-00.txt */ static DATA_BLOB encode_krb5_setpw(const char *principal, const char *password) { @@ -101,7 +111,8 @@ static DATA_BLOB encode_krb5_setpw(const char *principal, const char *password) return ret; } -static krb5_error_code build_setpw_request(krb5_context context, +static krb5_error_code build_kpasswd_request(uint16 pversion, + krb5_context context, krb5_auth_context auth_context, krb5_data *ap_req, const char *princ, @@ -123,7 +134,14 @@ static krb5_error_code build_setpw_request(krb5_context context, return ret; } - setpw = encode_krb5_setpw(princ, passwd); + /* handle protocol differences in chpw and setpw */ + if (pversion == KRB5_KPASSWD_VERS_CHANGEPW) + setpw = data_blob(passwd, strlen(passwd)); + else if (pversion == KRB5_KPASSWD_VERS_SETPW || + pversion == KRB5_KPASSWD_VERS_SETPW_MS) + setpw = encode_krb5_setpw(princ, passwd); + else + return EINVAL; encoded_setpw.data = setpw.data; encoded_setpw.length = setpw.length; @@ -144,7 +162,7 @@ static krb5_error_code build_setpw_request(krb5_context context, /* see the RFC for details */ p = ((char *)packet->data) + 2; - RSSVAL(p, 0, 0xff80); + RSSVAL(p, 0, pversion); p += 2; RSSVAL(p, 0, ap_req->length); p += 2; @@ -160,6 +178,49 @@ static krb5_error_code build_setpw_request(krb5_context context, return 0; } +static krb5_error_code krb5_setpw_result_code_string(krb5_context context, + int result_code, + char **code_string) +{ + switch (result_code) { + case KRB5_KPASSWD_MALFORMED: + *code_string = "Malformed request error"; + break; + case KRB5_KPASSWD_HARDERROR: + *code_string = "Server error"; + break; + case KRB5_KPASSWD_AUTHERROR: + *code_string = "Authentication error"; + break; + case KRB5_KPASSWD_SOFTERROR: + *code_string = "Password change rejected"; + break; + case KRB5_KPASSWD_ACCESSDENIED: + *code_string = "Client does not have proper authorization"; + break; + case KRB5_KPASSWD_BAD_VERSION: + *code_string = "Protocol version not supported"; + break; + case KRB5_KPASSWD_INITIAL_FLAG_NEEDED: + *code_string = "Authorization ticket must have initial flag set"; + break; + case KRB5_KPASSWD_POLICY_REJECT: + *code_string = "Password rejected due to policy requirements"; + break; + case KRB5_KPASSWD_BAD_PRINCIPAL: + *code_string = "Target principal does not exist"; + break; + case KRB5_KPASSWD_ETYPE_NOSUPP: + *code_string = "Unsupported encryption type"; + break; + default: + *code_string = "Password change failed"; + break; + } + + return(0); +} + static krb5_error_code parse_setpw_reply(krb5_context context, krb5_auth_context auth_context, krb5_data *packet) @@ -194,8 +255,11 @@ static krb5_error_code parse_setpw_reply(krb5_context context, p += 2; vnum = RSVAL(p, 0); p += 2; - - if (vnum != KRB5_KPASSWD_VERS_SETPW && vnum != KRB5_KPASSWD_VERS_CHANGEPW) { + + /* FIXME: According to standard there is only one type of reply */ + if (vnum != KRB5_KPASSWD_VERS_SETPW && + vnum != KRB5_KPASSWD_VERS_SETPW_MS && + vnum != KRB5_KPASSWD_VERS_CHANGEPW) { DEBUG(1,("Bad vnum (%d) from kpasswd server\n", vnum)); return KRB5KDC_ERR_BAD_PVNO; } @@ -247,96 +311,56 @@ static krb5_error_code parse_setpw_reply(krb5_context context, free(clearresult.data); if ((res_code < KRB5_KPASSWD_SUCCESS) || - (res_code >= KRB5_KPASSWD_ACCESSDENIED)) { + (res_code > KRB5_KPASSWD_ETYPE_NOSUPP)) { return KRB5KRB_AP_ERR_MODIFIED; } - - return 0; + + if(res_code == KRB5_KPASSWD_SUCCESS) + return 0; + else { + char *errstr; + krb5_setpw_result_code_string(context, res_code, &errstr); + DEBUG(1, ("Error changing password: %s\n", errstr)); + + switch(res_code) { + case KRB5_KPASSWD_ACCESSDENIED: + return KRB5KDC_ERR_BADOPTION; + break; + case KRB5_KPASSWD_INITIAL_FLAG_NEEDED: + return KV5M_ALT_METHOD; + break; + case KRB5_KPASSWD_ETYPE_NOSUPP: + return KRB5KDC_ERR_ETYPE_NOSUPP; + break; + case KRB5_KPASSWD_BAD_PRINCIPAL: + return KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN; + break; + case KRB5_KPASSWD_POLICY_REJECT: + return KRB5KDC_ERR_POLICY; + break; + default: + return KRB5KRB_ERR_GENERIC; + break; + } + } } -ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char *newpw, - int time_offset) +static ADS_STATUS do_krb5_kpasswd_request(krb5_context context, + const char *kdc_host, + uint16 pversion, + krb5_creds *credsp, + const char *princ, + const char *newpw) { - krb5_context context; krb5_auth_context auth_context = NULL; - krb5_principal principal; - char *princ_name; - char *realm; - krb5_creds creds, *credsp; - krb5_ccache ccache; krb5_data ap_req, chpw_req, chpw_rep; int ret, sock, addr_len; struct sockaddr remote_addr, local_addr; krb5_address local_kaddr, remote_kaddr; - ret = krb5_init_context(&context); - if (ret) { - DEBUG(1,("Failed to init krb5 context (%s)\n", error_message(ret))); - return ADS_ERROR_KRB5(ret); - } - - if (time_offset != 0) { - krb5_set_real_time(context, time(NULL) + time_offset, 0); - } - - ret = krb5_cc_default(context, &ccache); - if (ret) { - krb5_free_context(context); - DEBUG(1,("Failed to get default creds (%s)\n", error_message(ret))); - return ADS_ERROR_KRB5(ret); - } - - ZERO_STRUCT(creds); - - realm = strchr(princ, '@'); - realm++; - - asprintf(&princ_name, "kadmin/changepw@%s", realm); - ret = krb5_parse_name(context, princ_name, &creds.server); - if (ret) { - krb5_free_context(context); - DEBUG(1,("Failed to parse kadmin/changepw (%s)\n", error_message(ret))); - return ADS_ERROR_KRB5(ret); - } - free(princ_name); - - /* parse the principal we got as a function argument */ - ret = krb5_parse_name(context, princ, &principal); - if (ret) { - krb5_free_context(context); - DEBUG(1,("Failed to parse %s (%s)\n", princ_name, error_message(ret))); - return ADS_ERROR_KRB5(ret); - } - - krb5_princ_set_realm(context, creds.server, - krb5_princ_realm(context, principal)); - - ret = krb5_cc_get_principal(context, ccache, &creds.client); - if (ret) { - krb5_free_principal(context, principal); - krb5_free_context(context); - DEBUG(1,("Failed to get principal from ccache (%s)\n", - error_message(ret))); - return ADS_ERROR_KRB5(ret); - } - - ret = krb5_get_credentials(context, 0, ccache, &creds, &credsp); - if (ret) { - krb5_free_principal(context, creds.client); - krb5_free_principal(context, principal); - krb5_free_context(context); - DEBUG(1,("krb5_get_credentials failed (%s)\n", error_message(ret))); - return ADS_ERROR_KRB5(ret); - } - - /* we might have to call krb5_free_creds(...) from now on ... */ ret = krb5_mk_req_extended(context, &auth_context, AP_OPTS_USE_SUBKEY, NULL, credsp, &ap_req); if (ret) { - krb5_free_creds(context, credsp); - krb5_free_principal(context, creds.client); - krb5_free_principal(context, principal); - krb5_free_context(context); DEBUG(1,("krb5_mk_req_extended failed (%s)\n", error_message(ret))); return ADS_ERROR_KRB5(ret); } @@ -345,10 +369,7 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char if (sock == -1) { int rc = errno; free(ap_req.data); - krb5_free_creds(context, credsp); - krb5_free_principal(context, creds.client); - krb5_free_principal(context, principal); - krb5_free_context(context); + krb5_auth_con_free(context, auth_context); DEBUG(1,("failed to open kpasswd socket to %s (%s)\n", kdc_host, strerror(errno))); return ADS_ERROR_SYSTEM(rc); @@ -366,23 +387,17 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char if (ret) { close(sock); free(ap_req.data); - krb5_free_creds(context, credsp); - krb5_free_principal(context, creds.client); - krb5_free_principal(context, principal); - krb5_free_context(context); + krb5_auth_con_free(context, auth_context); DEBUG(1,("krb5_auth_con_setaddrs failed (%s)\n", error_message(ret))); return ADS_ERROR_KRB5(ret); } - ret = build_setpw_request(context, auth_context, &ap_req, + ret = build_kpasswd_request(pversion, context, auth_context, &ap_req, princ, newpw, &chpw_req); if (ret) { close(sock); free(ap_req.data); - krb5_free_creds(context, credsp); - krb5_free_principal(context, creds.client); - krb5_free_principal(context, principal); - krb5_free_context(context); + krb5_auth_con_free(context, auth_context); DEBUG(1,("build_setpw_request failed (%s)\n", error_message(ret))); return ADS_ERROR_KRB5(ret); } @@ -391,10 +406,7 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char close(sock); free(chpw_req.data); free(ap_req.data); - krb5_free_creds(context, credsp); - krb5_free_principal(context, creds.client); - krb5_free_principal(context, principal); - krb5_free_context(context); + krb5_auth_con_free(context, auth_context); DEBUG(1,("send of chpw failed (%s)\n", strerror(errno))); return ADS_ERROR_SYSTEM(errno); } @@ -406,10 +418,7 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char if (!chpw_rep.data) { close(sock); free(ap_req.data); - krb5_free_creds(context, credsp); - krb5_free_principal(context, creds.client); - krb5_free_principal(context, principal); - krb5_free_context(context); + krb5_auth_con_free(context, auth_context); DEBUG(1,("send of chpw failed (%s)\n", strerror(errno))); errno = ENOMEM; return ADS_ERROR_SYSTEM(errno); @@ -420,10 +429,7 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char close(sock); free(chpw_rep.data); free(ap_req.data); - krb5_free_creds(context, credsp); - krb5_free_principal(context, creds.client); - krb5_free_principal(context, principal); - krb5_free_context(context); + krb5_auth_con_free(context, auth_context); DEBUG(1,("recv of chpw reply failed (%s)\n", strerror(errno))); return ADS_ERROR_SYSTEM(errno); } @@ -435,10 +441,7 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char if (ret) { free(chpw_rep.data); free(ap_req.data); - krb5_free_creds(context, credsp); - krb5_free_principal(context, creds.client); - krb5_free_principal(context, principal); - krb5_free_context(context); + krb5_auth_con_free(context, auth_context); DEBUG(1,("krb5_auth_con_setaddrs on reply failed (%s)\n", error_message(ret))); return ADS_ERROR_KRB5(ret); @@ -449,22 +452,194 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char if (ret) { free(ap_req.data); - krb5_free_creds(context, credsp); - krb5_free_principal(context, creds.client); - krb5_free_principal(context, principal); - krb5_free_context(context); + krb5_auth_con_free(context, auth_context); DEBUG(1,("parse_setpw_reply failed (%s)\n", error_message(ret))); return ADS_ERROR_KRB5(ret); } free(ap_req.data); + krb5_auth_con_free(context, auth_context); + + return ADS_SUCCESS; +} + +ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char *newpw, + int time_offset) +{ + + ADS_STATUS aret; + krb5_error_code ret; + krb5_context context; + krb5_principal principal; + char *princ_name; + char *realm; + krb5_creds creds, *credsp; + krb5_ccache ccache; + + ret = krb5_init_context(&context); + if (ret) { + DEBUG(1,("Failed to init krb5 context (%s)\n", error_message(ret))); + return ADS_ERROR_KRB5(ret); + } + + if (time_offset != 0) { + krb5_set_real_time(context, time(NULL) + time_offset, 0); + } + + ret = krb5_cc_default(context, &ccache); + if (ret) { + krb5_free_context(context); + DEBUG(1,("Failed to get default creds (%s)\n", error_message(ret))); + return ADS_ERROR_KRB5(ret); + } + + ZERO_STRUCT(creds); + + realm = strchr(princ, '@'); + realm++; + + asprintf(&princ_name, "kadmin/changepw@%s", realm); + ret = krb5_parse_name(context, princ_name, &creds.server); + if (ret) { + krb5_free_context(context); + DEBUG(1,("Failed to parse kadmin/changepw (%s)\n", error_message(ret))); + return ADS_ERROR_KRB5(ret); + } + free(princ_name); + + /* parse the principal we got as a function argument */ + ret = krb5_parse_name(context, princ, &principal); + if (ret) { + krb5_free_context(context); + DEBUG(1,("Failed to parse %s (%s)\n", princ_name, error_message(ret))); + return ADS_ERROR_KRB5(ret); + } + + krb5_princ_set_realm(context, creds.server, + krb5_princ_realm(context, principal)); + + ret = krb5_cc_get_principal(context, ccache, &creds.client); + if (ret) { + krb5_free_principal(context, principal); + krb5_free_context(context); + DEBUG(1,("Failed to get principal from ccache (%s)\n", + error_message(ret))); + return ADS_ERROR_KRB5(ret); + } + + ret = krb5_get_credentials(context, 0, ccache, &creds, &credsp); + if (ret) { + krb5_free_principal(context, creds.client); + krb5_free_principal(context, principal); + krb5_free_context(context); + DEBUG(1,("krb5_get_credentials failed (%s)\n", error_message(ret))); + return ADS_ERROR_KRB5(ret); + } + + /* we might have to call krb5_free_creds(...) from now on ... */ + + aret = do_krb5_kpasswd_request(context, kdc_host, + KRB5_KPASSWD_VERS_SETPW_MS, + credsp, princ, newpw); + krb5_free_creds(context, credsp); krb5_free_principal(context, creds.client); + krb5_free_principal(context, creds.server); krb5_free_principal(context, principal); krb5_free_context(context); - return ADS_SUCCESS; + return aret; +} + +/* + we use a prompter to avoid a crash bug in the kerberos libs when + dealing with empty passwords + this prompter is just a string copy ... +*/ +static krb5_error_code +kerb_prompter(krb5_context ctx, void *data, + const char *name, + const char *banner, + int num_prompts, + krb5_prompt prompts[]) +{ + if (num_prompts == 0) return 0; + + memset(prompts[0].reply->data, 0, prompts[0].reply->length); + if (prompts[0].reply->length > 0) { + if (data) { + strncpy(prompts[0].reply->data, data, prompts[0].reply->length-1); + prompts[0].reply->length = strlen(prompts[0].reply->data); + } else { + prompts[0].reply->length = 0; + } + } + return 0; +} + +ADS_STATUS krb5_chg_password(const char *kdc_host, + const char *principal, + const char *oldpw, + const char *newpw, + int time_offset) +{ + ADS_STATUS aret; + krb5_error_code ret; + krb5_context context; + krb5_principal princ; + krb5_get_init_creds_opt opts; + krb5_creds creds; + char *chpw_princ = NULL, *password; + + ret = krb5_init_context(&context); + if (ret) { + DEBUG(1,("Failed to init krb5 context (%s)\n", error_message(ret))); + return ADS_ERROR_KRB5(ret); + } + + if ((ret = krb5_parse_name(context, principal, + &princ))) { + krb5_free_context(context); + DEBUG(1,("Failed to parse %s (%s)\n", principal, error_message(ret))); + return ADS_ERROR_KRB5(ret); + } + + krb5_get_init_creds_opt_init(&opts); + krb5_get_init_creds_opt_set_tkt_life(&opts, 5*60); + krb5_get_init_creds_opt_set_renew_life(&opts, 0); + krb5_get_init_creds_opt_set_forwardable(&opts, 0); + krb5_get_init_creds_opt_set_proxiable(&opts, 0); + + /* We have to obtain an INITIAL changepw ticket for changing password */ + asprintf(&chpw_princ, "kadmin/changepw@%s", + (char *) krb5_princ_realm(context, princ)); + password = strdup(oldpw); + ret = krb5_get_init_creds_password(context, &creds, princ, password, + kerb_prompter, NULL, + 0, chpw_princ, &opts); + SAFE_FREE(chpw_princ); + SAFE_FREE(password); + + if (ret) { + if (ret == KRB5KRB_AP_ERR_BAD_INTEGRITY) + DEBUG(1,("Password incorrect while getting initial ticket")); + else + DEBUG(1,("krb5_get_init_creds_password failed (%s)\n", error_message(ret))); + + krb5_free_principal(context, princ); + krb5_free_context(context); + return ADS_ERROR_KRB5(ret); + } + + aret = do_krb5_kpasswd_request(context, kdc_host, + KRB5_KPASSWD_VERS_CHANGEPW, + &creds, principal, newpw); + + krb5_free_principal(context, princ); + krb5_free_context(context); + + return aret; } @@ -480,7 +655,12 @@ ADS_STATUS kerberos_set_password(const char *kpasswd_server, return ADS_ERROR_KRB5(ret); } - return krb5_set_password(kpasswd_server, target_principal, new_password, time_offset); + if (!strcmp(auth_principal, target_principal)) + return krb5_chg_password(kpasswd_server, target_principal, + auth_password, new_password, time_offset); + else + return krb5_set_password(kpasswd_server, target_principal, + new_password, time_offset); } @@ -515,4 +695,6 @@ ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads, return status; } + + #endif diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 47a94f0a08..c92e481078 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1022,7 +1022,7 @@ char *ads_ou_string(const char *org_unit) static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, const char *org_unit) { - ADS_STATUS ret; + ADS_STATUS ret, status; char *host_spn, *host_upn, *new_dn, *samAccountName, *controlstr; char *ou_str; TALLOC_CTX *ctx; @@ -1089,9 +1089,21 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, ads_mod_str(ctx, &mods, "operatingSystem", "Samba"); ads_mod_str(ctx, &mods, "operatingSystemVersion", VERSION); - ads_gen_add(ads, new_dn, mods); - ret = ads_set_machine_sd(ads, hostname, new_dn); + ret = ads_gen_add(ads, new_dn, mods); + if (!ADS_ERR_OK(ret)) + goto done; + + /* Do not fail if we can't set security descriptor + * it shouldn't be mandatory and probably we just + * don't have enough rights to do it. + */ + status = ads_set_machine_sd(ads, hostname, new_dn); + + if (!ADS_ERR_OK(status)) { + DEBUG(0, ("Warning: ads_set_machine_sd: %s\n", + ads_errstr(status))); + } done: talloc_destroy(ctx); return ret; @@ -1406,7 +1418,7 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) **/ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) { - const char *attrs[] = {"ntSecurityDescriptor", "objectSid", 0}; + const char *attrs[] = {"nTSecurityDescriptor", "objectSid", 0}; char *exp = 0; size_t sd_size = 0; struct berval bval = {0, NULL}; @@ -1423,6 +1435,10 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) SEC_DESC *psd = 0; TALLOC_CTX *ctx = 0; + /* Avoid segmentation fault in prs_mem_free if + * we have to bail out before prs_init */ + ps_wire.is_dynamic = False; + if (!ads) return ADS_ERROR(LDAP_SERVER_DOWN); ret = ADS_ERROR(LDAP_SUCCESS); diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 7aa77bf2a2..29d4533a54 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -241,7 +241,12 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) ADS_STATUS status; krb5_principal principal; krb5_context ctx; - krb5_enctype enc_types[] = {ENCTYPE_DES_CBC_MD5, ENCTYPE_NULL}; + krb5_enctype enc_types[] = { +#ifdef ENCTYPE_ARCFOUR_HMAC + ENCTYPE_ARCFOUR_HMAC, +#endif + ENCTYPE_DES_CBC_MD5, + ENCTYPE_NULL}; gss_OID_desc nt_principal = {10, "\052\206\110\206\367\022\001\002\002\002"}; diff --git a/source3/libads/util.c b/source3/libads/util.c index 021f2d93e4..335cabc952 100644 --- a/source3/libads/util.c +++ b/source3/libads/util.c @@ -29,7 +29,7 @@ ADS_STATUS ads_change_trust_account_password(ADS_STRUCT *ads, char *host_princip char *new_password; char *service_principal; ADS_STATUS ret; - + if ((password = secrets_fetch_machine_password()) == NULL) { DEBUG(1,("Failed to retrieve password for principal %s\n", host_principal)); return ADS_ERROR_SYSTEM(ENOENT); @@ -38,15 +38,17 @@ ADS_STATUS ads_change_trust_account_password(ADS_STRUCT *ads, char *host_princip tmp_password = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH); new_password = strdup(tmp_password); asprintf(&service_principal, "HOST/%s", host_principal); - - ret = kerberos_set_password(ads->auth.kdc_server, host_principal, password, - service_principal, new_password, ads->auth.time_offset); + + ret = kerberos_set_password(ads->auth.kdc_server, service_principal, password, service_principal, new_password, ads->auth.time_offset); + + if (!ADS_ERR_OK(ret)) goto failed; if (!secrets_store_machine_password(new_password)) { DEBUG(1,("Failed to save machine password\n")); return ADS_ERROR_SYSTEM(EACCES); } +failed: SAFE_FREE(service_principal); SAFE_FREE(new_password); -- cgit From 030beddfb3c5208256c08b3cd2620332113f6308 Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Tue, 18 Feb 2003 14:59:21 +0000 Subject: Fix of two warnings. pull_ucs2_talloc function takes char** pointer, not (here explicitly casted) void** one. Rafal (This used to be commit e77c44efd95d42a8194f5c3d36c043f8e84dfd1d) --- source3/libads/ldap_printer.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index 87ea058896..f5cd4f2885 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -85,8 +85,7 @@ static BOOL map_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods, return False; if (value->size && *((smb_ucs2_t *) value->data_p)) { - pull_ucs2_talloc(ctx, (void **) &str_value, - (const smb_ucs2_t *) value->data_p); + pull_ucs2_talloc(ctx, &str_value, (const smb_ucs2_t *) value->data_p); status = ads_mod_str(ctx, mods, value->valuename, str_value); return ADS_ERR_OK(status); } @@ -155,9 +154,8 @@ static BOOL map_multi_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods, cur_str = (smb_ucs2_t *) value->data_p; for (i=0; i < num_vals; i++) - cur_str += pull_ucs2_talloc(ctx, - (void **) &str_values[i], - cur_str); + cur_str += pull_ucs2_talloc(ctx, &str_values[i], + cur_str); status = ads_mod_strlist(ctx, mods, value->valuename, (const char **) str_values); -- cgit From adfefcdcb6e9d8ea0458a11b6f684a5cf231c3ba Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Wed, 19 Feb 2003 01:16:40 +0000 Subject: Try to get heimdal working with HEAD. - Provide generic functions for - get valid encryption types - free encryption types - Add encryption type parm to generic function create_kerberos_key_from_string() - Try to merge the two versions (between HEAD and SAMBA_3_0) of kerberos_verify.c I think this should work for both MIT and heimdal, in HEAD. If all goes smooth, I'll move it over to 3.0 soon... (This used to be commit 45e409fc8da9f26cf888e13d004392660d7c55d4) --- source3/libads/kerberos_verify.c | 27 +++++++-------------------- 1 file changed, 7 insertions(+), 20 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index c1402b1370..17fecf60c8 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -36,8 +36,6 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, krb5_keytab keytab = NULL; krb5_data packet; krb5_ticket *tkt = NULL; - krb5_data salt; - krb5_encrypt_block eblock; int ret, i; krb5_keyblock * key; krb5_principal host_princ; @@ -92,17 +90,11 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, return NT_STATUS_LOGON_FAILURE; } - ret = krb5_principal2salt(context, host_princ, &salt); - if (ret) { - DEBUG(1,("krb5_principal2salt failed (%s)\n", error_message(ret))); - return NT_STATUS_LOGON_FAILURE; - } - if (!(key = (krb5_keyblock *)malloc(sizeof(*key)))) { return NT_STATUS_NO_MEMORY; } - if ((ret = krb5_get_permitted_enctypes(context, &enctypes))) { + if ((ret = get_kerberos_allowed_etypes(context, &enctypes))) { DEBUG(1,("krb5_get_permitted_enctypes failed (%s)\n", error_message(ret))); return NT_STATUS_LOGON_FAILURE; @@ -110,10 +102,7 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, /* we need to setup a auth context with each possible encoding type in turn */ for (i=0;enctypes[i];i++) { - krb5_use_enctype(context, &eblock, enctypes[i]); - - ret = krb5_string_to_key(context, &eblock, key, &password, &salt); - if (ret) { + if (create_kerberos_key_from_string(context, host_princ, &password, key, enctypes[i])) { continue; } @@ -124,7 +113,7 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, if (!(ret = krb5_rd_req(context, &auth_context, &packet, NULL, keytab, NULL, &tkt))) { - krb5_free_ktypes(context, enctypes); + free_kerberos_etypes(context, enctypes); auth_ok = True; break; } @@ -133,6 +122,7 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, if (!auth_ok) { DEBUG(3,("krb5_rd_req with auth failed (%s)\n", error_message(ret))); + SAFE_FREE(key); return NT_STATUS_LOGON_FAILURE; } @@ -140,11 +130,7 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, file_save("/tmp/ticket.dat", ticket->data, ticket->length); #endif - - if (tkt->enc_part2) { - *auth_data = data_blob(tkt->enc_part2->authorization_data[0]->contents, - tkt->enc_part2->authorization_data[0]->length); - } + get_auth_data_from_tkt(auth_data, tkt); #if 0 if (tkt->enc_part2) { @@ -154,7 +140,8 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, } #endif - if ((ret = krb5_unparse_name(context, tkt->enc_part2->client, principal))) { + if ((ret = krb5_unparse_name(context, get_principal_from_tkt(tkt), + principal))) { DEBUG(3,("krb5_unparse_name failed (%s)\n", error_message(ret))); return NT_STATUS_LOGON_FAILURE; -- cgit From 39daab943dbf2f24d3d74fba5a8d76ef58b7dabf Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 19 Feb 2003 11:35:02 +0000 Subject: Check return values of various join-related functions, and ensure we always compare push_* returns with (size_t)-1, not < 0. Andrew Bartlett (This used to be commit 63f5e92536c6bcac54b796d6e91b755e7d328f66) --- source3/libads/ldap.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index c92e481078..b7cfc8d84c 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -426,10 +426,10 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, return ADS_ERROR(LDAP_NO_MEMORY); /* 0 means the conversion worked but the result was empty - so we only fail if it's negative. In any case, it always + so we only fail if it's -1. In any case, it always at least nulls out the dest */ - if ((push_utf8_talloc(ctx, &utf8_exp, exp) < 0) || - (push_utf8_talloc(ctx, &utf8_path, bind_path) < 0)) { + if ((push_utf8_talloc(ctx, &utf8_exp, exp) == (size_t)-1) || + (push_utf8_talloc(ctx, &utf8_path, bind_path) == (size_t)-1)) { rc = LDAP_NO_MEMORY; goto done; } @@ -652,8 +652,8 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, /* 0 means the conversion worked but the result was empty so we only fail if it's negative. In any case, it always at least nulls out the dest */ - if ((push_utf8_talloc(ctx, &utf8_exp, exp) < 0) || - (push_utf8_talloc(ctx, &utf8_path, bind_path) < 0)) { + if ((push_utf8_talloc(ctx, &utf8_exp, exp) == (size_t)-1) || + (push_utf8_talloc(ctx, &utf8_path, bind_path) == (size_t)-1)) { DEBUG(1,("ads_do_search: push_utf8_talloc() failed!")); rc = LDAP_NO_MEMORY; goto done; @@ -1432,8 +1432,8 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) NTSTATUS status; ADS_STATUS ret; DOM_SID sid; - SEC_DESC *psd = 0; - TALLOC_CTX *ctx = 0; + SEC_DESC *psd = NULL; + TALLOC_CTX *ctx = NULL; /* Avoid segmentation fault in prs_mem_free if * we have to bail out before prs_init */ @@ -1464,7 +1464,11 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) goto ads_set_sd_error; } - ads_pull_sid(ads, msg, attrs[1], &sid); + if (!ads_pull_sid(ads, msg, attrs[1], &sid)) { + ret = ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); + goto ads_set_sd_error; + } + if (!(ctx = talloc_init("sec_io_desc"))) { ret = ADS_ERROR(LDAP_NO_MEMORY); goto ads_set_sd_error; @@ -1482,7 +1486,10 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) goto ads_set_sd_error; } - prs_init(&ps_wire, sd_size, ctx, MARSHALL); + if (!prs_init(&ps_wire, sd_size, ctx, MARSHALL)) { + ret = ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + } + if (!sec_io_desc("sd_wire", &psd, &ps_wire, 1)) { ret = ADS_ERROR(LDAP_NO_MEMORY); goto ads_set_sd_error; -- cgit From 251ea1e6776401005e302addd56a689c01924426 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 19 Feb 2003 12:31:16 +0000 Subject: Merge minor library fixes from HEAD to 3.0. - setenv() replacement - mimir's ASN1/SPNEGO typo fixes - (size_t)-1 fixes for push_* returns - function argument signed/unsigned correction - ASN1 error handling (ensure we don't use initiailsed data) - extra net ads join error checking - allow 'set security discriptor' to fail - escape ldap strings in libads. - getgrouplist() correctness fixes (include primary gid) Andrew Bartlett (This used to be commit e9d6e2ea9a3dc01d3849b925c50702cda6ddf225) --- source3/libads/ads_ldap.c | 12 ++++++++++- source3/libads/ldap.c | 49 +++++++++++++++++++++++++++++++------------ source3/libads/ldap_printer.c | 8 +++---- 3 files changed, 50 insertions(+), 19 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_ldap.c b/source3/libads/ads_ldap.c index 05b016539e..97f12de0f7 100644 --- a/source3/libads/ads_ldap.c +++ b/source3/libads/ads_ldap.c @@ -37,9 +37,16 @@ NTSTATUS ads_name_to_sid(ADS_STRUCT *ads, char *exp; uint32 t; NTSTATUS status = NT_STATUS_UNSUCCESSFUL; + char *escaped_name = escape_ldap_string_alloc(name); + char *escaped_realm = escape_ldap_string_alloc(ads->config.realm); + + if (!escaped_name || !escaped_realm) { + status = NT_STATUS_NO_MEMORY; + goto done; + } if (asprintf(&exp, "(|(sAMAccountName=%s)(userPrincipalName=%s@%s))", - name, name, ads->config.realm) == -1) { + escaped_name, escaped_name, escaped_realm) == -1) { DEBUG(1,("ads_name_to_sid: asprintf failed!\n")); status = NT_STATUS_NO_MEMORY; goto done; @@ -77,6 +84,9 @@ NTSTATUS ads_name_to_sid(ADS_STRUCT *ads, done: if (res) ads_msgfree(ads, res); + SAFE_FREE(escaped_name); + SAFE_FREE(escaped_realm); + return status; } diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 47a94f0a08..b7cfc8d84c 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -426,10 +426,10 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, return ADS_ERROR(LDAP_NO_MEMORY); /* 0 means the conversion worked but the result was empty - so we only fail if it's negative. In any case, it always + so we only fail if it's -1. In any case, it always at least nulls out the dest */ - if ((push_utf8_talloc(ctx, &utf8_exp, exp) < 0) || - (push_utf8_talloc(ctx, &utf8_path, bind_path) < 0)) { + if ((push_utf8_talloc(ctx, &utf8_exp, exp) == (size_t)-1) || + (push_utf8_talloc(ctx, &utf8_path, bind_path) == (size_t)-1)) { rc = LDAP_NO_MEMORY; goto done; } @@ -652,8 +652,8 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, /* 0 means the conversion worked but the result was empty so we only fail if it's negative. In any case, it always at least nulls out the dest */ - if ((push_utf8_talloc(ctx, &utf8_exp, exp) < 0) || - (push_utf8_talloc(ctx, &utf8_path, bind_path) < 0)) { + if ((push_utf8_talloc(ctx, &utf8_exp, exp) == (size_t)-1) || + (push_utf8_talloc(ctx, &utf8_path, bind_path) == (size_t)-1)) { DEBUG(1,("ads_do_search: push_utf8_talloc() failed!")); rc = LDAP_NO_MEMORY; goto done; @@ -1022,7 +1022,7 @@ char *ads_ou_string(const char *org_unit) static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, const char *org_unit) { - ADS_STATUS ret; + ADS_STATUS ret, status; char *host_spn, *host_upn, *new_dn, *samAccountName, *controlstr; char *ou_str; TALLOC_CTX *ctx; @@ -1089,9 +1089,21 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, ads_mod_str(ctx, &mods, "operatingSystem", "Samba"); ads_mod_str(ctx, &mods, "operatingSystemVersion", VERSION); - ads_gen_add(ads, new_dn, mods); - ret = ads_set_machine_sd(ads, hostname, new_dn); + ret = ads_gen_add(ads, new_dn, mods); + + if (!ADS_ERR_OK(ret)) + goto done; + + /* Do not fail if we can't set security descriptor + * it shouldn't be mandatory and probably we just + * don't have enough rights to do it. + */ + status = ads_set_machine_sd(ads, hostname, new_dn); + if (!ADS_ERR_OK(status)) { + DEBUG(0, ("Warning: ads_set_machine_sd: %s\n", + ads_errstr(status))); + } done: talloc_destroy(ctx); return ret; @@ -1406,7 +1418,7 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) **/ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) { - const char *attrs[] = {"ntSecurityDescriptor", "objectSid", 0}; + const char *attrs[] = {"nTSecurityDescriptor", "objectSid", 0}; char *exp = 0; size_t sd_size = 0; struct berval bval = {0, NULL}; @@ -1420,8 +1432,12 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) NTSTATUS status; ADS_STATUS ret; DOM_SID sid; - SEC_DESC *psd = 0; - TALLOC_CTX *ctx = 0; + SEC_DESC *psd = NULL; + TALLOC_CTX *ctx = NULL; + + /* Avoid segmentation fault in prs_mem_free if + * we have to bail out before prs_init */ + ps_wire.is_dynamic = False; if (!ads) return ADS_ERROR(LDAP_SERVER_DOWN); @@ -1448,7 +1464,11 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) goto ads_set_sd_error; } - ads_pull_sid(ads, msg, attrs[1], &sid); + if (!ads_pull_sid(ads, msg, attrs[1], &sid)) { + ret = ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); + goto ads_set_sd_error; + } + if (!(ctx = talloc_init("sec_io_desc"))) { ret = ADS_ERROR(LDAP_NO_MEMORY); goto ads_set_sd_error; @@ -1466,7 +1486,10 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) goto ads_set_sd_error; } - prs_init(&ps_wire, sd_size, ctx, MARSHALL); + if (!prs_init(&ps_wire, sd_size, ctx, MARSHALL)) { + ret = ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + } + if (!sec_io_desc("sd_wire", &psd, &ps_wire, 1)) { ret = ADS_ERROR(LDAP_NO_MEMORY); goto ads_set_sd_error; diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index 87ea058896..f5cd4f2885 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -85,8 +85,7 @@ static BOOL map_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods, return False; if (value->size && *((smb_ucs2_t *) value->data_p)) { - pull_ucs2_talloc(ctx, (void **) &str_value, - (const smb_ucs2_t *) value->data_p); + pull_ucs2_talloc(ctx, &str_value, (const smb_ucs2_t *) value->data_p); status = ads_mod_str(ctx, mods, value->valuename, str_value); return ADS_ERR_OK(status); } @@ -155,9 +154,8 @@ static BOOL map_multi_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods, cur_str = (smb_ucs2_t *) value->data_p; for (i=0; i < num_vals; i++) - cur_str += pull_ucs2_talloc(ctx, - (void **) &str_values[i], - cur_str); + cur_str += pull_ucs2_talloc(ctx, &str_values[i], + cur_str); status = ads_mod_strlist(ctx, mods, value->valuename, (const char **) str_values); -- cgit From ad03d0a4f885a87b5dbe7c88e507b302cf06ece2 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Wed, 19 Feb 2003 15:03:04 +0000 Subject: Fix segv in net ads join...an extra & was the culprit (This used to be commit 9874b233d55a0b1aea7eb033848f4b63a531833b) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index b7cfc8d84c..67669fc078 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1506,7 +1506,7 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) ret = ADS_ERROR(LDAP_NO_MEMORY); goto ads_set_sd_error; } - prs_copy_all_data_out((char *)&bval.bv_val, &ps_wire); + prs_copy_all_data_out(bval.bv_val, &ps_wire); ads_mod_ber(ctx, &mods, attrs[0], &bval); ret = ads_gen_mod(ads, dn, mods); -- cgit From 4560329abbdbdc9dea75f32422ba9b08bcfee726 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Wed, 19 Feb 2003 15:04:04 +0000 Subject: Fix segv in net ads join...an extra & was the culprit (This used to be commit 1a9050a6fe419e14fc82674d34cc4685a7532059) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index b7cfc8d84c..67669fc078 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1506,7 +1506,7 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) ret = ADS_ERROR(LDAP_NO_MEMORY); goto ads_set_sd_error; } - prs_copy_all_data_out((char *)&bval.bv_val, &ps_wire); + prs_copy_all_data_out(bval.bv_val, &ps_wire); ads_mod_ber(ctx, &mods, attrs[0], &bval); ret = ads_gen_mod(ads, dn, mods); -- cgit From 83a11f7f0e4331602acefcb3324be6f35f1fef0e Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Wed, 19 Feb 2003 15:48:12 +0000 Subject: Sync with HEAD for verifying kerberos tickets. (This used to be commit 77e1178a888f0d380a5ef94911a8f07bf04a7ba3) --- source3/libads/kerberos_verify.c | 45 +++++++++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 14 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 268326fca9..17fecf60c8 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -36,13 +36,15 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, krb5_keytab keytab = NULL; krb5_data packet; krb5_ticket *tkt = NULL; - int ret; + int ret, i; krb5_keyblock * key; krb5_principal host_princ; char *host_princ_s; fstring myname; char *password_s; krb5_data password; + krb5_enctype *enctypes = NULL; + BOOL auth_ok = False; if (!secrets_init()) { DEBUG(1,("secrets_init failed\n")); @@ -67,7 +69,6 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, ret = krb5_set_default_realm(context, ads->auth.realm); if (ret) { DEBUG(1,("krb5_set_default_realm failed (%s)\n", error_message(ret))); - ads_destroy(&ads); return NT_STATUS_LOGON_FAILURE; } @@ -93,27 +94,42 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, return NT_STATUS_NO_MEMORY; } - if (create_kerberos_key_from_string(context, host_princ, &password, key)) { - SAFE_FREE(key); + if ((ret = get_kerberos_allowed_etypes(context, &enctypes))) { + DEBUG(1,("krb5_get_permitted_enctypes failed (%s)\n", + error_message(ret))); return NT_STATUS_LOGON_FAILURE; } - - krb5_auth_con_setuseruserkey(context, auth_context, key); - packet.length = ticket->length; - packet.data = (krb5_pointer)ticket->data; + /* we need to setup a auth context with each possible encoding type in turn */ + for (i=0;enctypes[i];i++) { + if (create_kerberos_key_from_string(context, host_princ, &password, key, enctypes[i])) { + continue; + } -#if 0 - file_save("/tmp/ticket.dat", ticket->data, ticket->length); -#endif + krb5_auth_con_setuseruserkey(context, auth_context, key); + + packet.length = ticket->length; + packet.data = (krb5_pointer)ticket->data; - if ((ret = krb5_rd_req(context, &auth_context, &packet, - NULL, keytab, NULL, &tkt))) { + if (!(ret = krb5_rd_req(context, &auth_context, &packet, + NULL, keytab, NULL, &tkt))) { + free_kerberos_etypes(context, enctypes); + auth_ok = True; + break; + } + } + + if (!auth_ok) { DEBUG(3,("krb5_rd_req with auth failed (%s)\n", error_message(ret))); + SAFE_FREE(key); return NT_STATUS_LOGON_FAILURE; } +#if 0 + file_save("/tmp/ticket.dat", ticket->data, ticket->length); +#endif + get_auth_data_from_tkt(auth_data, tkt); #if 0 @@ -124,7 +140,8 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, } #endif - if ((ret = krb5_unparse_name(context, get_principal_from_tkt(tkt), principal))) { + if ((ret = krb5_unparse_name(context, get_principal_from_tkt(tkt), + principal))) { DEBUG(3,("krb5_unparse_name failed (%s)\n", error_message(ret))); return NT_STATUS_LOGON_FAILURE; -- cgit From de88e704ceb74e4811f14845556d65449f9d592b Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Wed, 19 Feb 2003 20:37:34 +0000 Subject: libads/krb5_setpw.c (This used to be commit 4c52d7bd933f61bdba3d4159a204fe16db3d4f0f) --- source3/libads/krb5_setpw.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index c3ec754e39..9d8fb8d24c 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -327,7 +327,8 @@ static krb5_error_code parse_setpw_reply(krb5_context context, return KRB5KDC_ERR_BADOPTION; break; case KRB5_KPASSWD_INITIAL_FLAG_NEEDED: - return KV5M_ALT_METHOD; + return KRB5KDC_ERR_BADOPTION; + /* return KV5M_ALT_METHOD; MIT-only define */ break; case KRB5_KPASSWD_ETYPE_NOSUPP: return KRB5KDC_ERR_ETYPE_NOSUPP; -- cgit From 301ebd6324138b9628638c0020597227d0cbf959 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 22 Feb 2003 00:54:08 +0000 Subject: Fix a DEBUG() formatting, add some more debug to our SID pulling code and inline the call to prs_copy_all_data_out() so that we can know we are not overrunning our buffer. Also check more return values. Andrew Bartlett (This used to be commit e3b73d5d658584428c81c9ef3ccf024687a56e2f) --- source3/libads/ldap.c | 51 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 18 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 67669fc078..bc90e90ea0 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -816,18 +816,18 @@ static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, { int curmod; LDAPMod **modlist = (LDAPMod **) *mods; - void **values; + struct berval **ber_values; + char **char_values; if (!invals) { - values = NULL; mod_op = LDAP_MOD_DELETE; } else { if (mod_op & LDAP_MOD_BVALUES) - values = (void **) ads_dup_values(ctx, - (const struct berval **)invals); + ber_values = ads_dup_values(ctx, + (const struct berval **)invals); else - values = (void **) ads_push_strvals(ctx, - (const char **) invals); + char_values = ads_push_strvals(ctx, + (const char **) invals); } /* find the first empty slot */ @@ -846,10 +846,14 @@ static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, if (!(modlist[curmod] = talloc_zero(ctx, sizeof(LDAPMod)))) return ADS_ERROR(LDAP_NO_MEMORY); modlist[curmod]->mod_type = talloc_strdup(ctx, name); - if (mod_op & LDAP_MOD_BVALUES) - modlist[curmod]->mod_bvalues = (struct berval **) values; - else - modlist[curmod]->mod_values = (char **) values; + if (mod_op & LDAP_MOD_BVALUES) { + modlist[curmod]->mod_bvalues = ber_values; + } else if (mod_op & LDAP_MOD_DELETE) { + modlist[curmod]->mod_values = NULL; + } else { + modlist[curmod]->mod_values = char_values; + } + modlist[curmod]->mod_op = mod_op; return ADS_ERROR(LDAP_SUCCESS); } @@ -1500,16 +1504,24 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) #endif if (!(mods = ads_init_mods(ctx))) return ADS_ERROR(LDAP_NO_MEMORY); - bval.bv_len = sd_size; - bval.bv_val = talloc(ctx, sd_size); + bval.bv_len = prs_offset(&ps_wire); + bval.bv_val = talloc(ctx, bval.bv_len); if (!bval.bv_val) { ret = ADS_ERROR(LDAP_NO_MEMORY); goto ads_set_sd_error; } - prs_copy_all_data_out(bval.bv_val, &ps_wire); - ads_mod_ber(ctx, &mods, attrs[0], &bval); - ret = ads_gen_mod(ads, dn, mods); + prs_set_offset(&ps_wire, 0); + + if (!prs_copy_data_out(bval.bv_val, &ps_wire, bval.bv_len)) { + ret = ADS_ERROR(LDAP_NO_MEMORY); + goto ads_set_sd_error; + } + + ret = ads_mod_ber(ctx, &mods, attrs[0], &bval); + if (ADS_ERR_OK(ret)) { + ret = ads_gen_mod(ads, dn, mods); + } ads_set_sd_error: ads_msgfree(ads, res); @@ -1554,7 +1566,7 @@ char *ads_pull_string(ADS_STRUCT *ads, char **values; char *ret = NULL; char *ux_string; - int rc; + size_t rc; values = ldap_get_values(ads->ld, msg, field); if (!values) @@ -1563,7 +1575,7 @@ char *ads_pull_string(ADS_STRUCT *ads, if (values[0]) { rc = pull_utf8_talloc(mem_ctx, &ux_string, values[0]); - if (rc != -1) + if (rc != (size_t)-1) ret = ux_string; } @@ -1725,8 +1737,11 @@ int ads_pull_sids(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, count = 0; for (i=0; values[i]; i++) { ret = sid_parse(values[i]->bv_val, values[i]->bv_len, &(*sids)[count]); - if (ret) + if (ret) { + fstring sid; + DEBUG(10, ("pulling SID: %s\n", sid_to_string(sid, &(*sids)[count]))); count++; + } } ldap_value_free_len(values); -- cgit From d1221c9b6c369113a531063737890b58d89bf6fe Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 24 Feb 2003 02:55:00 +0000 Subject: Merge from HEAD client-side authentication changes: - new kerberos code, allowing the account to change it's own password without special SD settings required - NTLMSSP client code, now seperated from cliconnect.c - NTLMv2 client code - SMB signing fixes Andrew Bartlett (This used to be commit 837680ca517982f2e5944730581a83012d4181ae) --- source3/libads/krb5_setpw.c | 429 +++++++++++++++++++++++++++++++------------- source3/libads/ldap.c | 51 ++++-- source3/libads/sasl.c | 7 +- source3/libads/util.c | 10 +- 4 files changed, 351 insertions(+), 146 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 087b0e9a71..9d8fb8d24c 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -24,13 +24,23 @@ #ifdef HAVE_KRB5 #define DEFAULT_KPASSWD_PORT 464 -#define KRB5_KPASSWD_VERS_CHANGEPW 1 -#define KRB5_KPASSWD_VERS_SETPW 0xff80 -#define KRB5_KPASSWD_ACCESSDENIED 5 -#define KRB5_KPASSWD_BAD_VERSION 6 - -/* This implements the Kerb password change protocol as specifed in - * kerb-chg-password-02.txt +#define KRB5_KPASSWD_VERS_CHANGEPW 1 +#define KRB5_KPASSWD_VERS_SETPW 2 +#define KRB5_KPASSWD_VERS_SETPW_MS 0xff80 +#define KRB5_KPASSWD_ACCESSDENIED 5 +#define KRB5_KPASSWD_BAD_VERSION 6 +#define KRB5_KPASSWD_INITIAL_FLAG_NEEDED 7 + +/* Those are defined by kerberos-set-passwd-02.txt and are probably + * not supported by M$ implementation */ +#define KRB5_KPASSWD_POLICY_REJECT 8 +#define KRB5_KPASSWD_BAD_PRINCIPAL 9 +#define KRB5_KPASSWD_ETYPE_NOSUPP 10 + +/* This implements kerberos password change protocol as specified in + * kerb-chg-password-02.txt and kerberos-set-passwd-02.txt + * as well as microsoft version of the protocol + * as specified in kerberos-set-passwd-00.txt */ static DATA_BLOB encode_krb5_setpw(const char *principal, const char *password) { @@ -101,7 +111,8 @@ static DATA_BLOB encode_krb5_setpw(const char *principal, const char *password) return ret; } -static krb5_error_code build_setpw_request(krb5_context context, +static krb5_error_code build_kpasswd_request(uint16 pversion, + krb5_context context, krb5_auth_context auth_context, krb5_data *ap_req, const char *princ, @@ -123,7 +134,14 @@ static krb5_error_code build_setpw_request(krb5_context context, return ret; } - setpw = encode_krb5_setpw(princ, passwd); + /* handle protocol differences in chpw and setpw */ + if (pversion == KRB5_KPASSWD_VERS_CHANGEPW) + setpw = data_blob(passwd, strlen(passwd)); + else if (pversion == KRB5_KPASSWD_VERS_SETPW || + pversion == KRB5_KPASSWD_VERS_SETPW_MS) + setpw = encode_krb5_setpw(princ, passwd); + else + return EINVAL; encoded_setpw.data = setpw.data; encoded_setpw.length = setpw.length; @@ -144,7 +162,7 @@ static krb5_error_code build_setpw_request(krb5_context context, /* see the RFC for details */ p = ((char *)packet->data) + 2; - RSSVAL(p, 0, 0xff80); + RSSVAL(p, 0, pversion); p += 2; RSSVAL(p, 0, ap_req->length); p += 2; @@ -160,6 +178,49 @@ static krb5_error_code build_setpw_request(krb5_context context, return 0; } +static krb5_error_code krb5_setpw_result_code_string(krb5_context context, + int result_code, + char **code_string) +{ + switch (result_code) { + case KRB5_KPASSWD_MALFORMED: + *code_string = "Malformed request error"; + break; + case KRB5_KPASSWD_HARDERROR: + *code_string = "Server error"; + break; + case KRB5_KPASSWD_AUTHERROR: + *code_string = "Authentication error"; + break; + case KRB5_KPASSWD_SOFTERROR: + *code_string = "Password change rejected"; + break; + case KRB5_KPASSWD_ACCESSDENIED: + *code_string = "Client does not have proper authorization"; + break; + case KRB5_KPASSWD_BAD_VERSION: + *code_string = "Protocol version not supported"; + break; + case KRB5_KPASSWD_INITIAL_FLAG_NEEDED: + *code_string = "Authorization ticket must have initial flag set"; + break; + case KRB5_KPASSWD_POLICY_REJECT: + *code_string = "Password rejected due to policy requirements"; + break; + case KRB5_KPASSWD_BAD_PRINCIPAL: + *code_string = "Target principal does not exist"; + break; + case KRB5_KPASSWD_ETYPE_NOSUPP: + *code_string = "Unsupported encryption type"; + break; + default: + *code_string = "Password change failed"; + break; + } + + return(0); +} + static krb5_error_code parse_setpw_reply(krb5_context context, krb5_auth_context auth_context, krb5_data *packet) @@ -194,8 +255,11 @@ static krb5_error_code parse_setpw_reply(krb5_context context, p += 2; vnum = RSVAL(p, 0); p += 2; - - if (vnum != KRB5_KPASSWD_VERS_SETPW && vnum != KRB5_KPASSWD_VERS_CHANGEPW) { + + /* FIXME: According to standard there is only one type of reply */ + if (vnum != KRB5_KPASSWD_VERS_SETPW && + vnum != KRB5_KPASSWD_VERS_SETPW_MS && + vnum != KRB5_KPASSWD_VERS_CHANGEPW) { DEBUG(1,("Bad vnum (%d) from kpasswd server\n", vnum)); return KRB5KDC_ERR_BAD_PVNO; } @@ -247,96 +311,57 @@ static krb5_error_code parse_setpw_reply(krb5_context context, free(clearresult.data); if ((res_code < KRB5_KPASSWD_SUCCESS) || - (res_code >= KRB5_KPASSWD_ACCESSDENIED)) { + (res_code > KRB5_KPASSWD_ETYPE_NOSUPP)) { return KRB5KRB_AP_ERR_MODIFIED; } - - return 0; + + if(res_code == KRB5_KPASSWD_SUCCESS) + return 0; + else { + char *errstr; + krb5_setpw_result_code_string(context, res_code, &errstr); + DEBUG(1, ("Error changing password: %s\n", errstr)); + + switch(res_code) { + case KRB5_KPASSWD_ACCESSDENIED: + return KRB5KDC_ERR_BADOPTION; + break; + case KRB5_KPASSWD_INITIAL_FLAG_NEEDED: + return KRB5KDC_ERR_BADOPTION; + /* return KV5M_ALT_METHOD; MIT-only define */ + break; + case KRB5_KPASSWD_ETYPE_NOSUPP: + return KRB5KDC_ERR_ETYPE_NOSUPP; + break; + case KRB5_KPASSWD_BAD_PRINCIPAL: + return KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN; + break; + case KRB5_KPASSWD_POLICY_REJECT: + return KRB5KDC_ERR_POLICY; + break; + default: + return KRB5KRB_ERR_GENERIC; + break; + } + } } -ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char *newpw, - int time_offset) +static ADS_STATUS do_krb5_kpasswd_request(krb5_context context, + const char *kdc_host, + uint16 pversion, + krb5_creds *credsp, + const char *princ, + const char *newpw) { - krb5_context context; krb5_auth_context auth_context = NULL; - krb5_principal principal; - char *princ_name; - char *realm; - krb5_creds creds, *credsp; - krb5_ccache ccache; krb5_data ap_req, chpw_req, chpw_rep; int ret, sock, addr_len; struct sockaddr remote_addr, local_addr; krb5_address local_kaddr, remote_kaddr; - ret = krb5_init_context(&context); - if (ret) { - DEBUG(1,("Failed to init krb5 context (%s)\n", error_message(ret))); - return ADS_ERROR_KRB5(ret); - } - - if (time_offset != 0) { - krb5_set_real_time(context, time(NULL) + time_offset, 0); - } - - ret = krb5_cc_default(context, &ccache); - if (ret) { - krb5_free_context(context); - DEBUG(1,("Failed to get default creds (%s)\n", error_message(ret))); - return ADS_ERROR_KRB5(ret); - } - - ZERO_STRUCT(creds); - - realm = strchr(princ, '@'); - realm++; - - asprintf(&princ_name, "kadmin/changepw@%s", realm); - ret = krb5_parse_name(context, princ_name, &creds.server); - if (ret) { - krb5_free_context(context); - DEBUG(1,("Failed to parse kadmin/changepw (%s)\n", error_message(ret))); - return ADS_ERROR_KRB5(ret); - } - free(princ_name); - - /* parse the principal we got as a function argument */ - ret = krb5_parse_name(context, princ, &principal); - if (ret) { - krb5_free_context(context); - DEBUG(1,("Failed to parse %s (%s)\n", princ_name, error_message(ret))); - return ADS_ERROR_KRB5(ret); - } - - krb5_princ_set_realm(context, creds.server, - krb5_princ_realm(context, principal)); - - ret = krb5_cc_get_principal(context, ccache, &creds.client); - if (ret) { - krb5_free_principal(context, principal); - krb5_free_context(context); - DEBUG(1,("Failed to get principal from ccache (%s)\n", - error_message(ret))); - return ADS_ERROR_KRB5(ret); - } - - ret = krb5_get_credentials(context, 0, ccache, &creds, &credsp); - if (ret) { - krb5_free_principal(context, creds.client); - krb5_free_principal(context, principal); - krb5_free_context(context); - DEBUG(1,("krb5_get_credentials failed (%s)\n", error_message(ret))); - return ADS_ERROR_KRB5(ret); - } - - /* we might have to call krb5_free_creds(...) from now on ... */ ret = krb5_mk_req_extended(context, &auth_context, AP_OPTS_USE_SUBKEY, NULL, credsp, &ap_req); if (ret) { - krb5_free_creds(context, credsp); - krb5_free_principal(context, creds.client); - krb5_free_principal(context, principal); - krb5_free_context(context); DEBUG(1,("krb5_mk_req_extended failed (%s)\n", error_message(ret))); return ADS_ERROR_KRB5(ret); } @@ -345,10 +370,7 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char if (sock == -1) { int rc = errno; free(ap_req.data); - krb5_free_creds(context, credsp); - krb5_free_principal(context, creds.client); - krb5_free_principal(context, principal); - krb5_free_context(context); + krb5_auth_con_free(context, auth_context); DEBUG(1,("failed to open kpasswd socket to %s (%s)\n", kdc_host, strerror(errno))); return ADS_ERROR_SYSTEM(rc); @@ -366,23 +388,17 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char if (ret) { close(sock); free(ap_req.data); - krb5_free_creds(context, credsp); - krb5_free_principal(context, creds.client); - krb5_free_principal(context, principal); - krb5_free_context(context); + krb5_auth_con_free(context, auth_context); DEBUG(1,("krb5_auth_con_setaddrs failed (%s)\n", error_message(ret))); return ADS_ERROR_KRB5(ret); } - ret = build_setpw_request(context, auth_context, &ap_req, + ret = build_kpasswd_request(pversion, context, auth_context, &ap_req, princ, newpw, &chpw_req); if (ret) { close(sock); free(ap_req.data); - krb5_free_creds(context, credsp); - krb5_free_principal(context, creds.client); - krb5_free_principal(context, principal); - krb5_free_context(context); + krb5_auth_con_free(context, auth_context); DEBUG(1,("build_setpw_request failed (%s)\n", error_message(ret))); return ADS_ERROR_KRB5(ret); } @@ -391,10 +407,7 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char close(sock); free(chpw_req.data); free(ap_req.data); - krb5_free_creds(context, credsp); - krb5_free_principal(context, creds.client); - krb5_free_principal(context, principal); - krb5_free_context(context); + krb5_auth_con_free(context, auth_context); DEBUG(1,("send of chpw failed (%s)\n", strerror(errno))); return ADS_ERROR_SYSTEM(errno); } @@ -406,10 +419,7 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char if (!chpw_rep.data) { close(sock); free(ap_req.data); - krb5_free_creds(context, credsp); - krb5_free_principal(context, creds.client); - krb5_free_principal(context, principal); - krb5_free_context(context); + krb5_auth_con_free(context, auth_context); DEBUG(1,("send of chpw failed (%s)\n", strerror(errno))); errno = ENOMEM; return ADS_ERROR_SYSTEM(errno); @@ -420,10 +430,7 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char close(sock); free(chpw_rep.data); free(ap_req.data); - krb5_free_creds(context, credsp); - krb5_free_principal(context, creds.client); - krb5_free_principal(context, principal); - krb5_free_context(context); + krb5_auth_con_free(context, auth_context); DEBUG(1,("recv of chpw reply failed (%s)\n", strerror(errno))); return ADS_ERROR_SYSTEM(errno); } @@ -435,10 +442,7 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char if (ret) { free(chpw_rep.data); free(ap_req.data); - krb5_free_creds(context, credsp); - krb5_free_principal(context, creds.client); - krb5_free_principal(context, principal); - krb5_free_context(context); + krb5_auth_con_free(context, auth_context); DEBUG(1,("krb5_auth_con_setaddrs on reply failed (%s)\n", error_message(ret))); return ADS_ERROR_KRB5(ret); @@ -449,22 +453,194 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char if (ret) { free(ap_req.data); - krb5_free_creds(context, credsp); - krb5_free_principal(context, creds.client); - krb5_free_principal(context, principal); - krb5_free_context(context); + krb5_auth_con_free(context, auth_context); DEBUG(1,("parse_setpw_reply failed (%s)\n", error_message(ret))); return ADS_ERROR_KRB5(ret); } free(ap_req.data); + krb5_auth_con_free(context, auth_context); + + return ADS_SUCCESS; +} + +ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char *newpw, + int time_offset) +{ + + ADS_STATUS aret; + krb5_error_code ret; + krb5_context context; + krb5_principal principal; + char *princ_name; + char *realm; + krb5_creds creds, *credsp; + krb5_ccache ccache; + + ret = krb5_init_context(&context); + if (ret) { + DEBUG(1,("Failed to init krb5 context (%s)\n", error_message(ret))); + return ADS_ERROR_KRB5(ret); + } + + if (time_offset != 0) { + krb5_set_real_time(context, time(NULL) + time_offset, 0); + } + + ret = krb5_cc_default(context, &ccache); + if (ret) { + krb5_free_context(context); + DEBUG(1,("Failed to get default creds (%s)\n", error_message(ret))); + return ADS_ERROR_KRB5(ret); + } + + ZERO_STRUCT(creds); + + realm = strchr(princ, '@'); + realm++; + + asprintf(&princ_name, "kadmin/changepw@%s", realm); + ret = krb5_parse_name(context, princ_name, &creds.server); + if (ret) { + krb5_free_context(context); + DEBUG(1,("Failed to parse kadmin/changepw (%s)\n", error_message(ret))); + return ADS_ERROR_KRB5(ret); + } + free(princ_name); + + /* parse the principal we got as a function argument */ + ret = krb5_parse_name(context, princ, &principal); + if (ret) { + krb5_free_context(context); + DEBUG(1,("Failed to parse %s (%s)\n", princ_name, error_message(ret))); + return ADS_ERROR_KRB5(ret); + } + + krb5_princ_set_realm(context, creds.server, + krb5_princ_realm(context, principal)); + + ret = krb5_cc_get_principal(context, ccache, &creds.client); + if (ret) { + krb5_free_principal(context, principal); + krb5_free_context(context); + DEBUG(1,("Failed to get principal from ccache (%s)\n", + error_message(ret))); + return ADS_ERROR_KRB5(ret); + } + + ret = krb5_get_credentials(context, 0, ccache, &creds, &credsp); + if (ret) { + krb5_free_principal(context, creds.client); + krb5_free_principal(context, principal); + krb5_free_context(context); + DEBUG(1,("krb5_get_credentials failed (%s)\n", error_message(ret))); + return ADS_ERROR_KRB5(ret); + } + + /* we might have to call krb5_free_creds(...) from now on ... */ + + aret = do_krb5_kpasswd_request(context, kdc_host, + KRB5_KPASSWD_VERS_SETPW_MS, + credsp, princ, newpw); + krb5_free_creds(context, credsp); krb5_free_principal(context, creds.client); + krb5_free_principal(context, creds.server); krb5_free_principal(context, principal); krb5_free_context(context); - return ADS_SUCCESS; + return aret; +} + +/* + we use a prompter to avoid a crash bug in the kerberos libs when + dealing with empty passwords + this prompter is just a string copy ... +*/ +static krb5_error_code +kerb_prompter(krb5_context ctx, void *data, + const char *name, + const char *banner, + int num_prompts, + krb5_prompt prompts[]) +{ + if (num_prompts == 0) return 0; + + memset(prompts[0].reply->data, 0, prompts[0].reply->length); + if (prompts[0].reply->length > 0) { + if (data) { + strncpy(prompts[0].reply->data, data, prompts[0].reply->length-1); + prompts[0].reply->length = strlen(prompts[0].reply->data); + } else { + prompts[0].reply->length = 0; + } + } + return 0; +} + +ADS_STATUS krb5_chg_password(const char *kdc_host, + const char *principal, + const char *oldpw, + const char *newpw, + int time_offset) +{ + ADS_STATUS aret; + krb5_error_code ret; + krb5_context context; + krb5_principal princ; + krb5_get_init_creds_opt opts; + krb5_creds creds; + char *chpw_princ = NULL, *password; + + ret = krb5_init_context(&context); + if (ret) { + DEBUG(1,("Failed to init krb5 context (%s)\n", error_message(ret))); + return ADS_ERROR_KRB5(ret); + } + + if ((ret = krb5_parse_name(context, principal, + &princ))) { + krb5_free_context(context); + DEBUG(1,("Failed to parse %s (%s)\n", principal, error_message(ret))); + return ADS_ERROR_KRB5(ret); + } + + krb5_get_init_creds_opt_init(&opts); + krb5_get_init_creds_opt_set_tkt_life(&opts, 5*60); + krb5_get_init_creds_opt_set_renew_life(&opts, 0); + krb5_get_init_creds_opt_set_forwardable(&opts, 0); + krb5_get_init_creds_opt_set_proxiable(&opts, 0); + + /* We have to obtain an INITIAL changepw ticket for changing password */ + asprintf(&chpw_princ, "kadmin/changepw@%s", + (char *) krb5_princ_realm(context, princ)); + password = strdup(oldpw); + ret = krb5_get_init_creds_password(context, &creds, princ, password, + kerb_prompter, NULL, + 0, chpw_princ, &opts); + SAFE_FREE(chpw_princ); + SAFE_FREE(password); + + if (ret) { + if (ret == KRB5KRB_AP_ERR_BAD_INTEGRITY) + DEBUG(1,("Password incorrect while getting initial ticket")); + else + DEBUG(1,("krb5_get_init_creds_password failed (%s)\n", error_message(ret))); + + krb5_free_principal(context, princ); + krb5_free_context(context); + return ADS_ERROR_KRB5(ret); + } + + aret = do_krb5_kpasswd_request(context, kdc_host, + KRB5_KPASSWD_VERS_CHANGEPW, + &creds, principal, newpw); + + krb5_free_principal(context, princ); + krb5_free_context(context); + + return aret; } @@ -480,7 +656,12 @@ ADS_STATUS kerberos_set_password(const char *kpasswd_server, return ADS_ERROR_KRB5(ret); } - return krb5_set_password(kpasswd_server, target_principal, new_password, time_offset); + if (!strcmp(auth_principal, target_principal)) + return krb5_chg_password(kpasswd_server, target_principal, + auth_password, new_password, time_offset); + else + return krb5_set_password(kpasswd_server, target_principal, + new_password, time_offset); } @@ -515,4 +696,6 @@ ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads, return status; } + + #endif diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 67669fc078..bc90e90ea0 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -816,18 +816,18 @@ static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, { int curmod; LDAPMod **modlist = (LDAPMod **) *mods; - void **values; + struct berval **ber_values; + char **char_values; if (!invals) { - values = NULL; mod_op = LDAP_MOD_DELETE; } else { if (mod_op & LDAP_MOD_BVALUES) - values = (void **) ads_dup_values(ctx, - (const struct berval **)invals); + ber_values = ads_dup_values(ctx, + (const struct berval **)invals); else - values = (void **) ads_push_strvals(ctx, - (const char **) invals); + char_values = ads_push_strvals(ctx, + (const char **) invals); } /* find the first empty slot */ @@ -846,10 +846,14 @@ static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, if (!(modlist[curmod] = talloc_zero(ctx, sizeof(LDAPMod)))) return ADS_ERROR(LDAP_NO_MEMORY); modlist[curmod]->mod_type = talloc_strdup(ctx, name); - if (mod_op & LDAP_MOD_BVALUES) - modlist[curmod]->mod_bvalues = (struct berval **) values; - else - modlist[curmod]->mod_values = (char **) values; + if (mod_op & LDAP_MOD_BVALUES) { + modlist[curmod]->mod_bvalues = ber_values; + } else if (mod_op & LDAP_MOD_DELETE) { + modlist[curmod]->mod_values = NULL; + } else { + modlist[curmod]->mod_values = char_values; + } + modlist[curmod]->mod_op = mod_op; return ADS_ERROR(LDAP_SUCCESS); } @@ -1500,16 +1504,24 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) #endif if (!(mods = ads_init_mods(ctx))) return ADS_ERROR(LDAP_NO_MEMORY); - bval.bv_len = sd_size; - bval.bv_val = talloc(ctx, sd_size); + bval.bv_len = prs_offset(&ps_wire); + bval.bv_val = talloc(ctx, bval.bv_len); if (!bval.bv_val) { ret = ADS_ERROR(LDAP_NO_MEMORY); goto ads_set_sd_error; } - prs_copy_all_data_out(bval.bv_val, &ps_wire); - ads_mod_ber(ctx, &mods, attrs[0], &bval); - ret = ads_gen_mod(ads, dn, mods); + prs_set_offset(&ps_wire, 0); + + if (!prs_copy_data_out(bval.bv_val, &ps_wire, bval.bv_len)) { + ret = ADS_ERROR(LDAP_NO_MEMORY); + goto ads_set_sd_error; + } + + ret = ads_mod_ber(ctx, &mods, attrs[0], &bval); + if (ADS_ERR_OK(ret)) { + ret = ads_gen_mod(ads, dn, mods); + } ads_set_sd_error: ads_msgfree(ads, res); @@ -1554,7 +1566,7 @@ char *ads_pull_string(ADS_STRUCT *ads, char **values; char *ret = NULL; char *ux_string; - int rc; + size_t rc; values = ldap_get_values(ads->ld, msg, field); if (!values) @@ -1563,7 +1575,7 @@ char *ads_pull_string(ADS_STRUCT *ads, if (values[0]) { rc = pull_utf8_talloc(mem_ctx, &ux_string, values[0]); - if (rc != -1) + if (rc != (size_t)-1) ret = ux_string; } @@ -1725,8 +1737,11 @@ int ads_pull_sids(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, count = 0; for (i=0; values[i]; i++) { ret = sid_parse(values[i]->bv_val, values[i]->bv_len, &(*sids)[count]); - if (ret) + if (ret) { + fstring sid; + DEBUG(10, ("pulling SID: %s\n", sid_to_string(sid, &(*sids)[count]))); count++; + } } ldap_value_free_len(values); diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 7aa77bf2a2..29d4533a54 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -241,7 +241,12 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) ADS_STATUS status; krb5_principal principal; krb5_context ctx; - krb5_enctype enc_types[] = {ENCTYPE_DES_CBC_MD5, ENCTYPE_NULL}; + krb5_enctype enc_types[] = { +#ifdef ENCTYPE_ARCFOUR_HMAC + ENCTYPE_ARCFOUR_HMAC, +#endif + ENCTYPE_DES_CBC_MD5, + ENCTYPE_NULL}; gss_OID_desc nt_principal = {10, "\052\206\110\206\367\022\001\002\002\002"}; diff --git a/source3/libads/util.c b/source3/libads/util.c index 021f2d93e4..335cabc952 100644 --- a/source3/libads/util.c +++ b/source3/libads/util.c @@ -29,7 +29,7 @@ ADS_STATUS ads_change_trust_account_password(ADS_STRUCT *ads, char *host_princip char *new_password; char *service_principal; ADS_STATUS ret; - + if ((password = secrets_fetch_machine_password()) == NULL) { DEBUG(1,("Failed to retrieve password for principal %s\n", host_principal)); return ADS_ERROR_SYSTEM(ENOENT); @@ -38,15 +38,17 @@ ADS_STATUS ads_change_trust_account_password(ADS_STRUCT *ads, char *host_princip tmp_password = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH); new_password = strdup(tmp_password); asprintf(&service_principal, "HOST/%s", host_principal); - - ret = kerberos_set_password(ads->auth.kdc_server, host_principal, password, - service_principal, new_password, ads->auth.time_offset); + + ret = kerberos_set_password(ads->auth.kdc_server, service_principal, password, service_principal, new_password, ads->auth.time_offset); + + if (!ADS_ERR_OK(ret)) goto failed; if (!secrets_store_machine_password(new_password)) { DEBUG(1,("Failed to save machine password\n")); return ADS_ERROR_SYSTEM(EACCES); } +failed: SAFE_FREE(service_principal); SAFE_FREE(new_password); -- cgit From a65b65c87a61ed602cce36a24c14c02ad3b373bc Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 24 Feb 2003 03:43:49 +0000 Subject: Make sure these values are never uninitialsised. (This used to be commit eacb8dde7afa16d86586c6c896ffb6692dc53bf6) --- source3/libads/ldap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index bc90e90ea0..29f44672f4 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -816,8 +816,8 @@ static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, { int curmod; LDAPMod **modlist = (LDAPMod **) *mods; - struct berval **ber_values; - char **char_values; + struct berval **ber_values = NULL; + char **char_values = NULL; if (!invals) { mod_op = LDAP_MOD_DELETE; -- cgit From 12f2ebf7f006369477824d9b4b917847d63a68af Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 24 Feb 2003 03:45:02 +0000 Subject: Always initialise (This used to be commit ff2b5b2f85f2d9dade67077cea1b68719cf65352) --- source3/libads/ldap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index bc90e90ea0..29f44672f4 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -816,8 +816,8 @@ static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, { int curmod; LDAPMod **modlist = (LDAPMod **) *mods; - struct berval **ber_values; - char **char_values; + struct berval **ber_values = NULL; + char **char_values = NULL; if (!invals) { mod_op = LDAP_MOD_DELETE; -- cgit From eb64538dba772a9846c05e2712839dbaa12c39a1 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 24 Feb 2003 11:09:21 +0000 Subject: Patch from Luke Howard to add mutual kerberos authentication, and SMB session keys for kerberos authentication. Andrew Bartlett (This used to be commit 8b798f03dbbdd670ff9af4eb46f7b0845c611e0f) --- source3/libads/kerberos_verify.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 17fecf60c8..4d9a1bf765 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -3,7 +3,7 @@ kerberos utility library Copyright (C) Andrew Tridgell 2001 Copyright (C) Remus Koos 2001 - + Copyright (C) Luke Howard 2003 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -29,7 +29,9 @@ authorization_data if available */ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, - char **principal, DATA_BLOB *auth_data) + char **principal, DATA_BLOB *auth_data, + DATA_BLOB *ap_rep, + uint8 session_key[16]) { krb5_context context; krb5_auth_context auth_context = NULL; @@ -122,10 +124,24 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, if (!auth_ok) { DEBUG(3,("krb5_rd_req with auth failed (%s)\n", error_message(ret))); - SAFE_FREE(key); return NT_STATUS_LOGON_FAILURE; } + ret = krb5_mk_rep(context, auth_context, &packet); + if (ret) { + DEBUG(3,("Failed to generate mutual authentication reply (%s)\n", + error_message(ret))); + krb5_auth_con_free(context, auth_context); + return NT_STATUS_LOGON_FAILURE; + } + + *ap_rep = data_blob(packet.data, packet.length); + free(packet.data); + + krb5_get_smb_session_key(context, auth_context, session_key); + DEBUG(0,("SMB session key (from ticket) follows:\n")); + dump_data(0, session_key, 16); + #if 0 file_save("/tmp/ticket.dat", ticket->data, ticket->length); #endif @@ -134,20 +150,24 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, #if 0 if (tkt->enc_part2) { - file_save("/tmp/authdata.dat", + file_save("/tmp/authdata.dat", tkt->enc_part2->authorization_data[0]->contents, tkt->enc_part2->authorization_data[0]->length); - } #endif if ((ret = krb5_unparse_name(context, get_principal_from_tkt(tkt), principal))) { DEBUG(3,("krb5_unparse_name failed (%s)\n", error_message(ret))); + data_blob_free(auth_data); + data_blob_free(ap_rep); + krb5_auth_con_free(context, auth_context); return NT_STATUS_LOGON_FAILURE; } + krb5_auth_con_free(context, auth_context); + return NT_STATUS_OK; } -#endif +#endif /* HAVE_KRB5 */ -- cgit From d116f2c884ce66f69df2973faf34f20a1a7ec988 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 25 Feb 2003 02:23:19 +0000 Subject: tokenGroups are SIDs, so dump them as such. (This used to be commit 43f07e9de70ad9993265e28a54239caba0121ab6) --- source3/libads/ldap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 29f44672f4..67827d27f3 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1215,6 +1215,7 @@ static BOOL ads_dump_field(char *field, void **values, void *data_area) {"nTSecurityDescriptor", False, dump_sd}, {"dnsRecord", False, dump_binary}, {"objectSid", False, dump_sid}, + {"tokenGroups", False, dump_sid}, {NULL, True, NULL} }; int i; -- cgit From 211dd28a7aef367b7d3c99c249a8c036370328f7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 5 Mar 2003 01:34:34 +0000 Subject: More const fixes. Jeremy. (This used to be commit fa93763248f2043395e4cfc70b8afd81e28b2b75) --- source3/libads/krb5_setpw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 9d8fb8d24c..ac7377cd2f 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -180,7 +180,7 @@ static krb5_error_code build_kpasswd_request(uint16 pversion, static krb5_error_code krb5_setpw_result_code_string(krb5_context context, int result_code, - char **code_string) + const char **code_string) { switch (result_code) { case KRB5_KPASSWD_MALFORMED: @@ -318,7 +318,7 @@ static krb5_error_code parse_setpw_reply(krb5_context context, if(res_code == KRB5_KPASSWD_SUCCESS) return 0; else { - char *errstr; + const char *errstr; krb5_setpw_result_code_string(context, res_code, &errstr); DEBUG(1, ("Error changing password: %s\n", errstr)); -- cgit From 7a9987481e70676918488b05e5dda44754e825e1 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 5 Mar 2003 01:34:37 +0000 Subject: More const fixes. Jeremy. (This used to be commit 7b945e10a6c636c0b0aabc841803bf44405cb2ae) --- source3/libads/krb5_setpw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 9d8fb8d24c..ac7377cd2f 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -180,7 +180,7 @@ static krb5_error_code build_kpasswd_request(uint16 pversion, static krb5_error_code krb5_setpw_result_code_string(krb5_context context, int result_code, - char **code_string) + const char **code_string) { switch (result_code) { case KRB5_KPASSWD_MALFORMED: @@ -318,7 +318,7 @@ static krb5_error_code parse_setpw_reply(krb5_context context, if(res_code == KRB5_KPASSWD_SUCCESS) return 0; else { - char *errstr; + const char *errstr; krb5_setpw_result_code_string(context, res_code, &errstr); DEBUG(1, ("Error changing password: %s\n", errstr)); -- cgit From 02abe94f81136f85dc72b7015213871831ce2e1a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 12 Mar 2003 10:56:55 +0000 Subject: - Fix a double-free (I can't say I understand the code, but it matches the other cases and keeps valgrind quiet). - Add static Andrew Bartlett (This used to be commit e9da9c500b96a828d744e7a1c64427fc01153310) --- source3/libads/krb5_setpw.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index ac7377cd2f..29bf1a427c 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -546,7 +546,6 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char krb5_free_creds(context, credsp); krb5_free_principal(context, creds.client); - krb5_free_principal(context, creds.server); krb5_free_principal(context, principal); krb5_free_context(context); @@ -579,11 +578,11 @@ kerb_prompter(krb5_context ctx, void *data, return 0; } -ADS_STATUS krb5_chg_password(const char *kdc_host, - const char *principal, - const char *oldpw, - const char *newpw, - int time_offset) +static ADS_STATUS krb5_chg_password(const char *kdc_host, + const char *principal, + const char *oldpw, + const char *newpw, + int time_offset) { ADS_STATUS aret; krb5_error_code ret; -- cgit From 2f62a72d9aebf3cfe9aa60a0bdc73f1ae477d5b2 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 16 Mar 2003 02:14:05 +0000 Subject: Changes to help the kerberos change password code work on systems that have some of the labels 'duplicated' (ie, the defines double-up). Also, to an ads_connect() to try and find our KDC. (So we don't segfualt *every* time) Andrew Bartlett (This used to be commit 56dce7ddad118051c93c62507234efca3920bc9b) --- source3/libads/krb5_setpw.c | 66 ++++++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 37 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 29bf1a427c..214871b3fb 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -178,47 +178,39 @@ static krb5_error_code build_kpasswd_request(uint16 pversion, return 0; } +static const struct kpasswd_errors { + int result_code; + const char *error_string; +} kpasswd_errors[] = { + {KRB5_KPASSWD_MALFORMED, "Malformed request error"}, + {KRB5_KPASSWD_HARDERROR, "Server error"}, + {KRB5_KPASSWD_AUTHERROR, "Authentication error"}, + {KRB5_KPASSWD_SOFTERROR, "Password change rejected"}, + {KRB5_KPASSWD_ACCESSDENIED, "Client does not have proper authorization"}, + {KRB5_KPASSWD_BAD_VERSION, "Protocol version not supported"}, + {KRB5_KPASSWD_INITIAL_FLAG_NEEDED, "Authorization ticket must have initial flag set"}, + {KRB5_KPASSWD_POLICY_REJECT, "Password rejected due to policy requirements"}, + {KRB5_KPASSWD_BAD_PRINCIPAL, "Target principal does not exist"}, + {KRB5_KPASSWD_ETYPE_NOSUPP, "Unsupported encryption type"}, + {0, NULL} +}; + static krb5_error_code krb5_setpw_result_code_string(krb5_context context, int result_code, const char **code_string) { - switch (result_code) { - case KRB5_KPASSWD_MALFORMED: - *code_string = "Malformed request error"; - break; - case KRB5_KPASSWD_HARDERROR: - *code_string = "Server error"; - break; - case KRB5_KPASSWD_AUTHERROR: - *code_string = "Authentication error"; - break; - case KRB5_KPASSWD_SOFTERROR: - *code_string = "Password change rejected"; - break; - case KRB5_KPASSWD_ACCESSDENIED: - *code_string = "Client does not have proper authorization"; - break; - case KRB5_KPASSWD_BAD_VERSION: - *code_string = "Protocol version not supported"; - break; - case KRB5_KPASSWD_INITIAL_FLAG_NEEDED: - *code_string = "Authorization ticket must have initial flag set"; - break; - case KRB5_KPASSWD_POLICY_REJECT: - *code_string = "Password rejected due to policy requirements"; - break; - case KRB5_KPASSWD_BAD_PRINCIPAL: - *code_string = "Target principal does not exist"; - break; - case KRB5_KPASSWD_ETYPE_NOSUPP: - *code_string = "Unsupported encryption type"; - break; - default: - *code_string = "Password change failed"; - break; - } - - return(0); + unsigned int idx = 0; + + while (kpasswd_errors[idx].error_string != NULL) { + if (kpasswd_errors[idx].result_code == + result_code) { + *code_string = kpasswd_errors[idx].error_string; + return 0; + } + idx++; + } + *code_string = "Password change failed"; + return (0); } static krb5_error_code parse_setpw_reply(krb5_context context, -- cgit From aa4bfd47113e0212aa72be067c20da56b8381648 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 17 Mar 2003 22:41:14 +0000 Subject: merge from HEAD - dump tokenGroups as sids. (This used to be commit f0daa15521e6352e25aa998f7e682f448e0fe51a) --- source3/libads/ldap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 29f44672f4..67827d27f3 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1215,6 +1215,7 @@ static BOOL ads_dump_field(char *field, void **values, void *data_area) {"nTSecurityDescriptor", False, dump_sd}, {"dnsRecord", False, dump_binary}, {"objectSid", False, dump_sid}, + {"tokenGroups", False, dump_sid}, {NULL, True, NULL} }; int i; -- cgit From f06d1b240a0cc15bc50c907198c06fcd826d63b2 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 17 Mar 2003 22:46:12 +0000 Subject: The kerberos_verify compoenent of the SessionSetup sync with HEAD. Andrew Bartlett (This used to be commit 64796ed27a3842be1dde52dd4f46698e95961767) --- source3/libads/kerberos_verify.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 17fecf60c8..4d9a1bf765 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -3,7 +3,7 @@ kerberos utility library Copyright (C) Andrew Tridgell 2001 Copyright (C) Remus Koos 2001 - + Copyright (C) Luke Howard 2003 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -29,7 +29,9 @@ authorization_data if available */ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, - char **principal, DATA_BLOB *auth_data) + char **principal, DATA_BLOB *auth_data, + DATA_BLOB *ap_rep, + uint8 session_key[16]) { krb5_context context; krb5_auth_context auth_context = NULL; @@ -122,10 +124,24 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, if (!auth_ok) { DEBUG(3,("krb5_rd_req with auth failed (%s)\n", error_message(ret))); - SAFE_FREE(key); return NT_STATUS_LOGON_FAILURE; } + ret = krb5_mk_rep(context, auth_context, &packet); + if (ret) { + DEBUG(3,("Failed to generate mutual authentication reply (%s)\n", + error_message(ret))); + krb5_auth_con_free(context, auth_context); + return NT_STATUS_LOGON_FAILURE; + } + + *ap_rep = data_blob(packet.data, packet.length); + free(packet.data); + + krb5_get_smb_session_key(context, auth_context, session_key); + DEBUG(0,("SMB session key (from ticket) follows:\n")); + dump_data(0, session_key, 16); + #if 0 file_save("/tmp/ticket.dat", ticket->data, ticket->length); #endif @@ -134,20 +150,24 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, #if 0 if (tkt->enc_part2) { - file_save("/tmp/authdata.dat", + file_save("/tmp/authdata.dat", tkt->enc_part2->authorization_data[0]->contents, tkt->enc_part2->authorization_data[0]->length); - } #endif if ((ret = krb5_unparse_name(context, get_principal_from_tkt(tkt), principal))) { DEBUG(3,("krb5_unparse_name failed (%s)\n", error_message(ret))); + data_blob_free(auth_data); + data_blob_free(ap_rep); + krb5_auth_con_free(context, auth_context); return NT_STATUS_LOGON_FAILURE; } + krb5_auth_con_free(context, auth_context); + return NT_STATUS_OK; } -#endif +#endif /* HAVE_KRB5 */ -- cgit From 83a580f49a3a7f5aff0aab3946faee0892239251 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 17 Mar 2003 22:58:24 +0000 Subject: Merge from HEAD: net ads password Heimdal compile fixes. Andrew Bartlett (This used to be commit 3aa4f923e99f453310bb4a8d43ce43757591909d) --- source3/libads/krb5_setpw.c | 66 ++++++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 37 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index ac7377cd2f..a5b9eee4ce 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -178,47 +178,39 @@ static krb5_error_code build_kpasswd_request(uint16 pversion, return 0; } +static const struct kpasswd_errors { + int result_code; + const char *error_string; +} kpasswd_errors[] = { + {KRB5_KPASSWD_MALFORMED, "Malformed request error"}, + {KRB5_KPASSWD_HARDERROR, "Server error"}, + {KRB5_KPASSWD_AUTHERROR, "Authentication error"}, + {KRB5_KPASSWD_SOFTERROR, "Password change rejected"}, + {KRB5_KPASSWD_ACCESSDENIED, "Client does not have proper authorization"}, + {KRB5_KPASSWD_BAD_VERSION, "Protocol version not supported"}, + {KRB5_KPASSWD_INITIAL_FLAG_NEEDED, "Authorization ticket must have initial flag set"}, + {KRB5_KPASSWD_POLICY_REJECT, "Password rejected due to policy requirements"}, + {KRB5_KPASSWD_BAD_PRINCIPAL, "Target principal does not exist"}, + {KRB5_KPASSWD_ETYPE_NOSUPP, "Unsupported encryption type"}, + {0, NULL} +}; + static krb5_error_code krb5_setpw_result_code_string(krb5_context context, int result_code, const char **code_string) { - switch (result_code) { - case KRB5_KPASSWD_MALFORMED: - *code_string = "Malformed request error"; - break; - case KRB5_KPASSWD_HARDERROR: - *code_string = "Server error"; - break; - case KRB5_KPASSWD_AUTHERROR: - *code_string = "Authentication error"; - break; - case KRB5_KPASSWD_SOFTERROR: - *code_string = "Password change rejected"; - break; - case KRB5_KPASSWD_ACCESSDENIED: - *code_string = "Client does not have proper authorization"; - break; - case KRB5_KPASSWD_BAD_VERSION: - *code_string = "Protocol version not supported"; - break; - case KRB5_KPASSWD_INITIAL_FLAG_NEEDED: - *code_string = "Authorization ticket must have initial flag set"; - break; - case KRB5_KPASSWD_POLICY_REJECT: - *code_string = "Password rejected due to policy requirements"; - break; - case KRB5_KPASSWD_BAD_PRINCIPAL: - *code_string = "Target principal does not exist"; - break; - case KRB5_KPASSWD_ETYPE_NOSUPP: - *code_string = "Unsupported encryption type"; - break; - default: - *code_string = "Password change failed"; - break; - } - - return(0); + unsigned int idx = 0; + + while (kpasswd_errors[idx].error_string != NULL) { + if (kpasswd_errors[idx].result_code == + result_code) { + *code_string = kpasswd_errors[idx].error_string; + return 0; + } + idx++; + } + *code_string = "Password change failed"; + return (0); } static krb5_error_code parse_setpw_reply(krb5_context context, -- cgit From 4905ba282fc1692b74208b177e934cdebd447c66 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 25 Mar 2003 14:46:11 +0000 Subject: - Support building all auth modules as .so's - Change 2 variable names to avoid conflicts (patch by Stephan Kulow ) (This used to be commit 71b05cd14ae6df8340730e7bad1c783dc278c5d3) --- source3/libads/ldap.c | 66 ++++++++++++++++++++++----------------------- source3/libads/ldap_utils.c | 10 +++---- 2 files changed, 38 insertions(+), 38 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 67827d27f3..baedfb28db 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -401,7 +401,7 @@ static char **ads_pull_strvals(TALLOC_CTX *ctx, const char **in_vals) * @param ads connection to ads server * @param bind_path Base dn for the search * @param scope Scope of search (LDAP_BASE | LDAP_ONE | LDAP_SUBTREE) - * @param exp Search expression - specified in local charset + * @param expr Search expression - specified in local charset * @param attrs Attributes to retrieve - specified in utf8 or ascii * @param res ** which will contain results - free res* with ads_msgfree() * @param count Number of entries retrieved on this page @@ -409,12 +409,12 @@ static char **ads_pull_strvals(TALLOC_CTX *ctx, const char **in_vals) * @return status of search **/ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, - int scope, const char *exp, + int scope, const char *expr, const char **attrs, void **res, int *count, void **cookie) { int rc, i, version; - char *utf8_exp, *utf8_path, **search_attrs; + char *utf8_expr, *utf8_path, **search_attrs; LDAPControl PagedResults, NoReferrals, *controls[3], **rcontrols; BerElement *cookie_be = NULL; struct berval *cookie_bv= NULL; @@ -428,7 +428,7 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, /* 0 means the conversion worked but the result was empty so we only fail if it's -1. In any case, it always at least nulls out the dest */ - if ((push_utf8_talloc(ctx, &utf8_exp, exp) == (size_t)-1) || + if ((push_utf8_talloc(ctx, &utf8_expr, expr) == (size_t)-1) || (push_utf8_talloc(ctx, &utf8_path, bind_path) == (size_t)-1)) { rc = LDAP_NO_MEMORY; goto done; @@ -489,7 +489,7 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, */ ldap_set_option(ads->ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF); - rc = ldap_search_ext_s(ads->ld, utf8_path, scope, utf8_exp, + rc = ldap_search_ext_s(ads->ld, utf8_path, scope, utf8_expr, search_attrs, 0, controls, NULL, NULL, LDAP_NO_LIMIT, (LDAPMessage **)res); @@ -497,7 +497,7 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, ber_bvfree(cookie_bv); if (rc) { - DEBUG(3,("ldap_search_ext_s(%s) -> %s\n", exp, ldap_err2string(rc))); + DEBUG(3,("ldap_search_ext_s(%s) -> %s\n", expr, ldap_err2string(rc))); goto done; } @@ -541,20 +541,20 @@ done: * @param ads connection to ads server * @param bind_path Base dn for the search * @param scope Scope of search (LDAP_BASE | LDAP_ONE | LDAP_SUBTREE) - * @param exp Search expression + * @param expr Search expression * @param attrs Attributes to retrieve * @param res ** which will contain results - free res* with ads_msgfree() * @return status of search **/ ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, - int scope, const char *exp, + int scope, const char *expr, const char **attrs, void **res) { void *cookie = NULL; int count = 0; ADS_STATUS status; - status = ads_do_paged_search(ads, bind_path, scope, exp, attrs, res, + status = ads_do_paged_search(ads, bind_path, scope, expr, attrs, res, &count, &cookie); if (!ADS_ERR_OK(status)) return status; @@ -564,7 +564,7 @@ ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, ADS_STATUS status2; LDAPMessage *msg, *next; - status2 = ads_do_paged_search(ads, bind_path, scope, exp, + status2 = ads_do_paged_search(ads, bind_path, scope, expr, attrs, &res2, &count, &cookie); if (!ADS_ERR_OK(status2)) break; @@ -588,14 +588,14 @@ ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, * @param ads connection to ads server * @param bind_path Base dn for the search * @param scope Scope of search (LDAP_BASE | LDAP_ONE | LDAP_SUBTREE) - * @param exp Search expression - specified in local charset + * @param expr Search expression - specified in local charset * @param attrs Attributes to retrieve - specified in UTF-8 or ascii * @param fn Function which takes attr name, values list, and data_area * @param data_area Pointer which is passed to function on each call * @return status of search **/ ADS_STATUS ads_do_search_all_fn(ADS_STRUCT *ads, const char *bind_path, - int scope, const char *exp, const char **attrs, + int scope, const char *expr, const char **attrs, BOOL(*fn)(char *, void **, void *), void *data_area) { @@ -604,7 +604,7 @@ ADS_STATUS ads_do_search_all_fn(ADS_STRUCT *ads, const char *bind_path, ADS_STATUS status; void *res; - status = ads_do_paged_search(ads, bind_path, scope, exp, attrs, &res, + status = ads_do_paged_search(ads, bind_path, scope, expr, attrs, &res, &count, &cookie); if (!ADS_ERR_OK(status)) return status; @@ -613,7 +613,7 @@ ADS_STATUS ads_do_search_all_fn(ADS_STRUCT *ads, const char *bind_path, ads_msgfree(ads, res); while (cookie) { - status = ads_do_paged_search(ads, bind_path, scope, exp, attrs, + status = ads_do_paged_search(ads, bind_path, scope, expr, attrs, &res, &count, &cookie); if (!ADS_ERR_OK(status)) break; @@ -630,18 +630,18 @@ ADS_STATUS ads_do_search_all_fn(ADS_STRUCT *ads, const char *bind_path, * @param ads connection to ads server * @param bind_path Base dn for the search * @param scope Scope of search (LDAP_BASE | LDAP_ONE | LDAP_SUBTREE) - * @param exp Search expression + * @param expr Search expression * @param attrs Attributes to retrieve * @param res ** which will contain results - free res* with ads_msgfree() * @return status of search **/ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, - const char *exp, + const char *expr, const char **attrs, void **res) { struct timeval timeout; int rc; - char *utf8_exp, *utf8_path, **search_attrs = NULL; + char *utf8_expr, *utf8_path, **search_attrs = NULL; TALLOC_CTX *ctx; if (!(ctx = talloc_init("ads_do_search"))) { @@ -652,7 +652,7 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, /* 0 means the conversion worked but the result was empty so we only fail if it's negative. In any case, it always at least nulls out the dest */ - if ((push_utf8_talloc(ctx, &utf8_exp, exp) == (size_t)-1) || + if ((push_utf8_talloc(ctx, &utf8_expr, expr) == (size_t)-1) || (push_utf8_talloc(ctx, &utf8_path, bind_path) == (size_t)-1)) { DEBUG(1,("ads_do_search: push_utf8_talloc() failed!")); rc = LDAP_NO_MEMORY; @@ -679,7 +679,7 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, /* see the note in ads_do_paged_search - we *must* disable referrals */ ldap_set_option(ads->ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF); - rc = ldap_search_ext_s(ads->ld, utf8_path, scope, utf8_exp, + rc = ldap_search_ext_s(ads->ld, utf8_path, scope, utf8_expr, search_attrs, 0, NULL, NULL, &timeout, LDAP_NO_LIMIT, (LDAPMessage **)res); @@ -698,16 +698,16 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, * Do a general ADS search * @param ads connection to ads server * @param res ** which will contain results - free res* with ads_msgfree() - * @param exp Search expression + * @param expr Search expression * @param attrs Attributes to retrieve * @return status of search **/ ADS_STATUS ads_search(ADS_STRUCT *ads, void **res, - const char *exp, + const char *expr, const char **attrs) { return ads_do_search(ads, ads->config.bind_path, LDAP_SCOPE_SUBTREE, - exp, attrs, res); + expr, attrs, res); } /** @@ -772,18 +772,18 @@ char *ads_get_dn(ADS_STRUCT *ads, void *res) ADS_STATUS ads_find_machine_acct(ADS_STRUCT *ads, void **res, const char *host) { ADS_STATUS status; - char *exp; + char *expr; const char *attrs[] = {"*", "nTSecurityDescriptor", NULL}; /* the easiest way to find a machine account anywhere in the tree is to look for hostname$ */ - if (asprintf(&exp, "(samAccountName=%s$)", host) == -1) { + if (asprintf(&expr, "(samAccountName=%s$)", host) == -1) { DEBUG(1, ("asprintf failed!\n")); return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); } - status = ads_search(ads, res, exp, attrs); - free(exp); + status = ads_search(ads, res, expr, attrs); + free(expr); return status; } @@ -1424,7 +1424,7 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) { const char *attrs[] = {"nTSecurityDescriptor", "objectSid", 0}; - char *exp = 0; + char *expr = 0; size_t sd_size = 0; struct berval bval = {0, NULL}; prs_struct ps_wire; @@ -1452,7 +1452,7 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); } - if (asprintf(&exp, "(samAccountName=%s$)", escaped_hostname) == -1) { + if (asprintf(&expr, "(samAccountName=%s$)", escaped_hostname) == -1) { DEBUG(1, ("ads_set_machine_sd: asprintf failed!\n")); SAFE_FREE(escaped_hostname); return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); @@ -1460,7 +1460,7 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) SAFE_FREE(escaped_hostname); - ret = ads_search(ads, (void *) &res, exp, attrs); + ret = ads_search(ads, (void *) &res, expr, attrs); if (!ADS_ERR_OK(ret)) return ret; @@ -2036,7 +2036,7 @@ but you need to force the bind path to match the configurationNamingContext from */ ADS_STATUS ads_workgroup_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char **workgroup) { - char *exp; + char *expr; ADS_STATUS rc; char **principles; char *prefix; @@ -2047,10 +2047,10 @@ ADS_STATUS ads_workgroup_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char **workg (*workgroup) = NULL; - asprintf(&exp, "(&(objectclass=computer)(dnshostname=%s.%s))", + asprintf(&expr, "(&(objectclass=computer)(dnshostname=%s.%s))", ads->config.ldap_server_name, ads->config.realm); - rc = ads_search(ads, &res, exp, attrs); - free(exp); + rc = ads_search(ads, &res, expr, attrs); + free(expr); if (!ADS_ERR_OK(rc)) { return rc; diff --git a/source3/libads/ldap_utils.c b/source3/libads/ldap_utils.c index 907f7c8aff..6855600288 100644 --- a/source3/libads/ldap_utils.c +++ b/source3/libads/ldap_utils.c @@ -28,7 +28,7 @@ this is supposed to catch dropped connections and auto-reconnect */ ADS_STATUS ads_do_search_retry(ADS_STRUCT *ads, const char *bind_path, int scope, - const char *exp, + const char *expr, const char **attrs, void **res) { ADS_STATUS status; @@ -46,10 +46,10 @@ ADS_STATUS ads_do_search_retry(ADS_STRUCT *ads, const char *bind_path, int scope return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); while (count--) { - status = ads_do_search_all(ads, bp, scope, exp, attrs, res); + status = ads_do_search_all(ads, bp, scope, expr, attrs, res); if (ADS_ERR_OK(status)) { DEBUG(5,("Search for %s gave %d replies\n", - exp, ads_count_replies(ads, *res))); + expr, ads_count_replies(ads, *res))); free(bp); return status; } @@ -79,11 +79,11 @@ ADS_STATUS ads_do_search_retry(ADS_STRUCT *ads, const char *bind_path, int scope ADS_STATUS ads_search_retry(ADS_STRUCT *ads, void **res, - const char *exp, + const char *expr, const char **attrs) { return ads_do_search_retry(ads, ads->config.bind_path, LDAP_SCOPE_SUBTREE, - exp, attrs, res); + expr, attrs, res); } ADS_STATUS ads_search_retry_dn(ADS_STRUCT *ads, void **res, -- cgit From 31e21b67d998eed46c55132cc6067db6163d30c1 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Mon, 7 Apr 2003 18:01:40 +0000 Subject: Decode the PAC! This patch just decodes it and then frees it, so it's just for doc purposes right now (you can see it in the debug logs). (This used to be commit 046c2087a11b9ce7a02aece34ffb129ce0d66b08) --- source3/libads/authdata.c | 495 +++++++++++++++++++++++++++++++++++++++ source3/libads/kerberos_verify.c | 6 + 2 files changed, 501 insertions(+) create mode 100644 source3/libads/authdata.c (limited to 'source3/libads') diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c new file mode 100644 index 0000000000..3d25aec205 --- /dev/null +++ b/source3/libads/authdata.c @@ -0,0 +1,495 @@ +/* + Unix SMB/CIFS implementation. + kerberos authorization data (PAC) utility library + Copyright (C) Jim McDonough 2003 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +#ifdef HAVE_KRB5 + +static DATA_BLOB unwrap_pac(DATA_BLOB *auth_data) +{ + DATA_BLOB pac_contents; + ASN1_DATA data; + int data_type; + + asn1_load(&data, *auth_data); + asn1_start_tag(&data, ASN1_SEQUENCE(0)); + asn1_start_tag(&data, ASN1_SEQUENCE(0)); + asn1_start_tag(&data, ASN1_CONTEXT(0)); + asn1_read_Integer(&data, &data_type); + asn1_end_tag(&data); + asn1_start_tag(&data, ASN1_CONTEXT(1)); + asn1_read_OctetString(&data, &pac_contents); + asn1_end_tag(&data); + asn1_end_tag(&data); + asn1_end_tag(&data); + return pac_contents; +} + +static BOOL pac_io_krb_sids(const char *desc, KRB_SID_AND_ATTRS *sid_and_attr, + prs_struct *ps, int depth) +{ + if (NULL == sid_and_attr) + return False; + + prs_debug(ps, depth, desc, "pac_io_krb_sids"); + depth++; + + if (UNMARSHALLING(ps)) { + sid_and_attr->sid = + (DOM_SID2 * ) prs_alloc_mem(ps, sizeof(DOM_SID2)); + if (!sid_and_attr->sid) { + DEBUG(3, ("No memory available\n")); + return False; + } + } + + if(!smb_io_dom_sid2("sid", sid_and_attr->sid, ps, depth)) + return False; + + return True; +} + + +static BOOL pac_io_krb_attrs(const char *desc, KRB_SID_AND_ATTRS *sid_and_attr, + prs_struct *ps, int depth) +{ + if (NULL == sid_and_attr) + return False; + + prs_debug(ps, depth, desc, "pac_io_krb_attrs"); + depth++; + + if (!prs_uint32("sid_ptr", ps, depth, &sid_and_attr->sid_ptr)) + return False; + if (!prs_uint32("attrs", ps, depth, &sid_and_attr->attrs)) + return False; + + return True; +} + +static BOOL pac_io_krb_sid_and_attr_array(const char *desc, + KRB_SID_AND_ATTR_ARRAY *array, + uint32 num, + prs_struct *ps, int depth) +{ + int i; + + if (NULL == array) + return False; + + prs_debug(ps, depth, desc, "pac_io_krb_sid_and_attr_array"); + depth++; + + + if (!prs_uint32("count", ps, depth, &array->count)) + return False; + + if (UNMARSHALLING(ps)) { + array->krb_sid_and_attrs = (KRB_SID_AND_ATTRS *) + prs_alloc_mem(ps, sizeof(KRB_SID_AND_ATTRS) * num); + if (!array->krb_sid_and_attrs) { + DEBUG(3, ("No memory available\n")); + return False; + } + } + + for (i=0; ikrb_sid_and_attrs[i], + ps, depth)) + return False; + + } + for (i=0; ikrb_sid_and_attrs[i], + ps, depth)) + return False; + + } + + return True; + +} + +static BOOL pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info, + prs_struct *ps, int depth) +{ + uint32 garbage; + if (NULL == info) + return False; + + prs_debug(ps, depth, desc, "pac_io_pac_logon_info"); + depth++; + + if (!prs_uint32("unknown", ps, depth, &garbage)) + return False; + if (!prs_uint32("unknown", ps, depth, &garbage)) + return False; + if (!prs_uint32("bufferlen", ps, depth, &garbage)) + return False; + if (!prs_uint32("bufferlenhi", ps, depth, &garbage)) + return False; + if (!prs_uint32("pointer", ps, depth, &garbage)) + return False; + + if (!smb_io_time("logon_time", &info->logon_time, ps, depth)) + return False; + if (!smb_io_time("logoff_time", &info->logoff_time, ps, depth)) + return False; + if (!smb_io_time("kickoff_time", &info->kickoff_time, ps, depth)) + return False; + if (!smb_io_time("pass_last_set_time", &info->pass_last_set_time, + ps, depth)) + return False; + if (!smb_io_time("pass_can_change_time", &info->pass_can_change_time, + ps, depth)) + return False; + if (!smb_io_time("pass_must_change_time", &info->pass_must_change_time, + ps, depth)) + return False; + + if (!smb_io_unihdr("hdr_user_name", &info->hdr_user_name, ps, depth)) + return False; + if (!smb_io_unihdr("hdr_full_name", &info->hdr_full_name, ps, depth)) + return False; + if (!smb_io_unihdr("hdr_logon_script", &info->hdr_logon_script, + ps, depth)) + return False; + if (!smb_io_unihdr("hdr_profile_path", &info->hdr_profile_path, + ps, depth)) + return False; + if (!smb_io_unihdr("hdr_home_dir", &info->hdr_home_dir, ps, depth)) + return False; + if (!smb_io_unihdr("hdr_dir_drive", &info->hdr_dir_drive, ps, depth)) + return False; + + if (!prs_uint16("logon_count", ps, depth, &info->logon_count)) + return False; + if (!prs_uint16("reserved12", ps, depth, &info->reserved12)) + return False; + if (!prs_uint32("user_rid", ps, depth, &info->user_rid)) + return False; + if (!prs_uint32("group_rid", ps, depth, &info->group_rid)) + return False; + if (!prs_uint32("group_count", ps, depth, &info->group_count)) + return False; + /* I haven't seen this contain anything yet, but when it does + we will have to make sure we decode the contents in the middle + all the unistr2s ... */ + if (!prs_uint32("group_mem_ptr", ps, depth, + &info->group_membership_ptr)) + return False; + if (!prs_uint32("user_flags", ps, depth, &info->user_flags)) + return False; + + if (!prs_uint32("reserved13.0", ps, depth, &info->reserved13[0])) + return False; + if (!prs_uint32("reserved13.1", ps, depth, &info->reserved13[1])) + return False; + if (!prs_uint32("reserved13.2", ps, depth, &info->reserved13[2])) + return False; + if (!prs_uint32("reserved13.3", ps, depth, &info->reserved13[3])) + return False; + + if (!smb_io_unihdr("hdr_dom_controller", + &info->hdr_dom_controller, ps, depth)) + return False; + if (!smb_io_unihdr("hdr_dom_name", &info->hdr_dom_name, ps, depth)) + return False; + + /* this should be followed, but just get ptr for now */ + if (!prs_uint32("ptr_dom_sid", ps, depth, &info->ptr_dom_sid)) + return False; + + if (!prs_uint32("reserved16.0", ps, depth, &info->reserved16[0])) + return False; + if (!prs_uint32("reserved16.1", ps, depth, &info->reserved16[1])) + return False; + + /* might be acb_info */ + if (!prs_uint32("reserved17", ps, depth, &info->reserved17)) + return False; + + + if (!prs_uint32("reserved18.0", ps, depth, &info->reserved18[0])) + return False; + if (!prs_uint32("reserved18.1", ps, depth, &info->reserved18[1])) + return False; + if (!prs_uint32("reserved18.2", ps, depth, &info->reserved18[2])) + return False; + if (!prs_uint32("reserved18.3", ps, depth, &info->reserved18[3])) + return False; + if (!prs_uint32("reserved18.4", ps, depth, &info->reserved18[4])) + return False; + if (!prs_uint32("reserved18.5", ps, depth, &info->reserved18[5])) + return False; + if (!prs_uint32("reserved18.6", ps, depth, &info->reserved18[6])) + return False; + + if (!prs_uint32("sid_count", ps, depth, &info->sid_count)) + return False; + if (!prs_uint32("ptr_extra_sids", ps, depth, &info->ptr_extra_sids)) + return False; + if (!prs_uint32("ptr_res_group_dom_sid", ps, depth, + &info->ptr_res_group_dom_sid)) + return False; + if (!prs_uint32("res_group_count", ps, depth, &info->res_group_count)) + return False; + if (!prs_uint32("ptr_res_group_sids", ps, depth, + &info->ptr_res_group_sids)) + return False; + + if(!smb_io_unistr2("uni_user_name", &info->uni_user_name, + info->hdr_user_name.buffer, ps, depth)) + return False; + if(!smb_io_unistr2("uni_full_name", &info->uni_full_name, + info->hdr_full_name.buffer, ps, depth)) + return False; + if(!smb_io_unistr2("uni_logon_script", &info->uni_logon_script, + info->hdr_logon_script.buffer, ps, depth)) + return False; + if(!smb_io_unistr2("uni_profile_path", &info->uni_profile_path, + info->hdr_profile_path.buffer, ps, depth)) + return False; + if(!smb_io_unistr2("uni_home_dir", &info->uni_home_dir, + info->hdr_home_dir.buffer, ps, depth)) + return False; + if(!smb_io_unistr2("uni_dir_drive", &info->uni_dir_drive, + info->hdr_dir_drive.buffer, ps, depth)) + return False; + + /* the group membership list will need to be handled here */ + + if(!smb_io_unistr2("uni_dom_controller", &info->uni_dom_controller, + info->hdr_dom_controller.buffer, ps, depth)) + return False; + if(!smb_io_unistr2("uni_dom_name", &info->uni_dom_name, + info->hdr_dom_name.buffer, ps, depth)) + return False; + + if(info->ptr_dom_sid) + if(!smb_io_dom_sid2("dom_sid", &info->dom_sid, ps, depth)) + return False; + + + if (info->sid_count && info->ptr_extra_sids) { + if (!pac_io_krb_sid_and_attr_array("extra_sids", + &info->extra_sids, + info->sid_count, + ps, depth)) + return False; + } + + + return True; +} + + +static BOOL pac_io_pac_signature_data(const char *desc, + PAC_SIGNATURE_DATA *data, uint32 length, + prs_struct *ps, int depth) +{ + uint32 siglen = length - sizeof(uint32); + if (NULL == data) + return False; + + prs_debug(ps, depth, desc, "pac_io_pac_signature_data"); + depth++; + + if (!prs_uint32("type", ps, depth, &data->type)) + return False; + if (UNMARSHALLING(ps)) { + data->signature = prs_alloc_mem(ps, siglen); + if (!data->signature) { + DEBUG(3, ("No memory available\n")); + return False; + } + } + if (!prs_uint8s(False, "signature", ps, depth, data->signature,siglen)) + return False; + + return True; +} + +static BOOL pac_io_pac_info_hdr_ctr(const char *desc, PAC_INFO_HDR *hdr, + prs_struct *ps, int depth) +{ + if (NULL == hdr) + return False; + + prs_debug(ps, depth, desc, "pac_io_pac_info_hdr_ctr"); + depth++; + + if (!prs_align(ps)) + return False; + + if (hdr->offset != prs_offset(ps)) { + DEBUG(5, ("offset in header(x%x) and data(x%x) do not match\n", + hdr->offset, prs_offset(ps))); + prs_set_offset(ps, hdr->offset); + } + + if (UNMARSHALLING(ps) && hdr->size > 0) { + hdr->ctr = (PAC_INFO_CTR *) + prs_alloc_mem(ps, sizeof(PAC_INFO_CTR)); + if (!hdr->ctr) { + DEBUG(3, ("No memory available\n")); + return False; + } + } + + switch(hdr->type) { + case PAC_TYPE_LOGON_INFO: + DEBUG(5, ("PAC_TYPE_LOGON_INFO\n")); + if (UNMARSHALLING(ps)) + hdr->ctr->pac.logon_info = (PAC_LOGON_INFO *) + prs_alloc_mem(ps, sizeof(PAC_LOGON_INFO)); + if (!hdr->ctr->pac.logon_info) { + DEBUG(3, ("No memory available\n")); + return False; + } + if (!pac_io_pac_logon_info(desc, hdr->ctr->pac.logon_info, + ps, depth)) + return False; + break; + + case PAC_TYPE_SERVER_CHECKSUM: + DEBUG(5, ("PAC_TYPE_SERVER_CHECKSUM\n")); + if (UNMARSHALLING(ps)) + hdr->ctr->pac.srv_cksum = (PAC_SIGNATURE_DATA *) + prs_alloc_mem(ps, sizeof(PAC_SIGNATURE_DATA)); + if (!hdr->ctr->pac.srv_cksum) { + DEBUG(3, ("No memory available\n")); + return False; + } + if (!pac_io_pac_signature_data(desc, hdr->ctr->pac.srv_cksum, + hdr->size, ps, depth)) + return False; + break; + + case PAC_TYPE_PRIVSVR_CHECKSUM: + DEBUG(5, ("PAC_TYPE_PRIVSVR_CHECKSUM\n")); + if (UNMARSHALLING(ps)) + hdr->ctr->pac.privsrv_cksum = (PAC_SIGNATURE_DATA *) + prs_alloc_mem(ps, sizeof(PAC_SIGNATURE_DATA)); + if (!hdr->ctr->pac.privsrv_cksum) { + DEBUG(3, ("No memory available\n")); + return False; + } + if (!pac_io_pac_signature_data(desc, + hdr->ctr->pac.privsrv_cksum, + hdr->size, ps, depth)) + return False; + break; + + default: + /* dont' know, so we need to skip it */ + DEBUG(3, ("unknown PAC type %d\n", hdr->type)); + prs_set_offset(ps, prs_offset(ps) + hdr->size); + } + + return True; +} + +static BOOL pac_io_pac_info_hdr(const char *desc, PAC_INFO_HDR *hdr, + prs_struct *ps, int depth) +{ + if (NULL == hdr) + return False; + + prs_debug(ps, depth, desc, "pac_io_pac_info_hdr"); + depth++; + + if (!prs_align(ps)) + return False; + if (!prs_uint32("type", ps, depth, &hdr->type)) + return False; + if (!prs_uint32("size", ps, depth, &hdr->size)) + return False; + if (!prs_uint32("offset", ps, depth, &hdr->offset)) + return False; + if (!prs_uint32("offsethi", ps, depth, &hdr->offsethi)) + return False; + + return True; +} + +static BOOL pac_io_pac_data(const char *desc, PAC_DATA *data, + prs_struct *ps, int depth) +{ + int i; + + if (NULL == data) + return False; + + prs_debug(ps, depth, desc, "pac_io_pac_data"); + depth++; + + if (!prs_align(ps)) + return False; + if (!prs_uint32("num_buffers", ps, depth, &data->num_buffers)) + return False; + if (!prs_uint32("version", ps, depth, &data->version)) + return False; + + if (UNMARSHALLING(ps) && data->num_buffers > 0) { + if ((data->pac_info_hdr_ptr = (PAC_INFO_HDR *) + prs_alloc_mem(ps, sizeof(PAC_INFO_HDR) * + data->num_buffers)) == NULL) { + return False; + } + } + + for (i=0; inum_buffers; i++) { + if (!pac_io_pac_info_hdr(desc, &data->pac_info_hdr_ptr[i], ps, + depth)) + return False; + } + + for (i=0; inum_buffers; i++) { + if (!pac_io_pac_info_hdr_ctr(desc, &data->pac_info_hdr_ptr[i], + ps, depth)) + return False; + } + + return True; +} + +PAC_DATA *decode_pac_data(DATA_BLOB *auth_data, TALLOC_CTX *ctx) +{ + DATA_BLOB pac_data_blob = unwrap_pac(auth_data); + prs_struct ps; + PAC_DATA *pac_data; + + DEBUG(5,("dump_pac_data\n")); + prs_init(&ps, pac_data_blob.length, ctx, UNMARSHALL); + prs_copy_data_in(&ps, pac_data_blob.data, pac_data_blob.length); + prs_set_offset(&ps, 0); + + pac_data = (PAC_DATA *) talloc_zero(ctx, sizeof(PAC_DATA)); + pac_io_pac_data("pac data", pac_data, &ps, 0); + + prs_mem_free(&ps); + + return pac_data; +} + +#endif diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 4d9a1bf765..56ec33b0a6 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -148,6 +148,12 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, get_auth_data_from_tkt(auth_data, tkt); + { + TALLOC_CTX *ctx = talloc_init("pac data"); + decode_pac_data(auth_data); + talloc_destroy(ctx); + } + #if 0 if (tkt->enc_part2) { file_save("/tmp/authdata.dat", -- cgit From 1f04eb2e2617ac05974c21bdac9ebb4781b5a9d9 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Wed, 9 Apr 2003 16:48:59 +0000 Subject: Complete what I've seen (and then some)t of the PAC. I haven't seen the rid+attr arrays for group membership, nor sids or the same kind of arrays for resource domains, so I don't know how that will work. Also, the PAC info type 10 is now decoded, but I don't know what it's for. It has an NTTIME, a 16-bit name length, and a username. According to M$, it's not needed, because they didn't doc it... (This used to be commit 28ab8504cf6c181866106e5cc626a5896283d0a9) --- source3/libads/authdata.c | 129 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 124 insertions(+), 5 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c index 3d25aec205..c554a02e90 100644 --- a/source3/libads/authdata.c +++ b/source3/libads/authdata.c @@ -42,6 +42,38 @@ static DATA_BLOB unwrap_pac(DATA_BLOB *auth_data) return pac_contents; } +static BOOL pac_io_unknown_type_10(const char *desc, UNKNOWN_TYPE_10 *type_10, + prs_struct *ps, int depth) +{ + if (NULL == type_10) + return False; + + prs_debug(ps, depth, desc, "pac_io_unknown_type_10"); + depth++; + + if (!smb_io_time("unknown_time", &type_10->unknown_time, ps, depth)) + return False; + + if (!prs_uint16("len", ps, depth, &type_10->len)) + return False; + + if (UNMARSHALLING(ps) && type_10->len) { + type_10->username = (uint16 *) prs_alloc_mem(ps, type_10->len); + if (!type_10->username) { + DEBUG(3, ("No memory available\n")); + return False; + } + } + + if (!prs_uint16s(True, "name", ps, depth, type_10->username, + (type_10->len / sizeof(uint16)))) + return False; + + return True; + +} + + static BOOL pac_io_krb_sids(const char *desc, KRB_SID_AND_ATTRS *sid_and_attr, prs_struct *ps, int depth) { @@ -129,6 +161,63 @@ static BOOL pac_io_krb_sid_and_attr_array(const char *desc, } +static BOOL pac_io_group_membership(const char *desc, + GROUP_MEMBERSHIP *membership, + prs_struct *ps, int depth) +{ + if (NULL == membership) + return False; + + prs_debug(ps, depth, desc, "pac_io_group_membership"); + depth++; + + if (!prs_uint32("rid", ps, depth, &membership->rid)) + return False; + if (!prs_uint32("attrs", ps, depth, &membership->attrs)) + return False; + + return True; +} + + +static BOOL pac_io_group_membership_array(const char *desc, + GROUP_MEMBERSHIP_ARRAY *array, + uint32 num, + prs_struct *ps, int depth) +{ + int i; + + if (NULL == array) + return False; + + prs_debug(ps, depth, desc, "pac_io_group_membership_array"); + depth++; + + + if (!prs_uint32("count", ps, depth, &array->count)) + return False; + + if (UNMARSHALLING(ps)) { + array->group_membership = (GROUP_MEMBERSHIP *) + prs_alloc_mem(ps, sizeof(GROUP_MEMBERSHIP) * num); + if (!array->group_membership) { + DEBUG(3, ("No memory available\n")); + return False; + } + } + + for (i=0; igroup_membership[i], + ps, depth)) + return False; + + } + + return True; + +} + static BOOL pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info, prs_struct *ps, int depth) { @@ -253,8 +342,7 @@ static BOOL pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info, return False; if (!prs_uint32("res_group_count", ps, depth, &info->res_group_count)) return False; - if (!prs_uint32("ptr_res_group_sids", ps, depth, - &info->ptr_res_group_sids)) + if (!prs_uint32("ptr_res_groups", ps, depth, &info->ptr_res_groups)) return False; if(!smb_io_unistr2("uni_user_name", &info->uni_user_name, @@ -276,7 +364,14 @@ static BOOL pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info, info->hdr_dir_drive.buffer, ps, depth)) return False; - /* the group membership list will need to be handled here */ + if (info->group_membership_ptr) { + if (!pac_io_group_membership_array("group membership", + &info->groups, + info->group_count, + ps, depth)) + return False; + } + if(!smb_io_unistr2("uni_dom_controller", &info->uni_dom_controller, info->hdr_dom_controller.buffer, ps, depth)) @@ -290,14 +385,24 @@ static BOOL pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info, return False; - if (info->sid_count && info->ptr_extra_sids) { + if (info->sid_count && info->ptr_extra_sids) if (!pac_io_krb_sid_and_attr_array("extra_sids", &info->extra_sids, info->sid_count, ps, depth)) return False; - } + if (info->ptr_res_group_dom_sid) + if (!smb_io_dom_sid2("res_group_dom_sid", + &info->res_group_dom_sid, ps, depth)) + return False; + + if (info->ptr_res_groups) + if (!pac_io_group_membership_array("res group membership", + &info->res_groups, + info->res_group_count, + ps, depth)) + return False; return True; } @@ -400,6 +505,20 @@ static BOOL pac_io_pac_info_hdr_ctr(const char *desc, PAC_INFO_HDR *hdr, return False; break; + case PAC_TYPE_UNKNOWN_10: + DEBUG(5, ("PAC_TYPE_UNKNOWN_10\n")); + if (UNMARSHALLING(ps)) + hdr->ctr->pac.type_10 = (UNKNOWN_TYPE_10 *) + prs_alloc_mem(ps, sizeof(UNKNOWN_TYPE_10)); + if (!hdr->ctr->pac.type_10) { + DEBUG(3, ("No memory available\n")); + return False; + } + if (!pac_io_unknown_type_10(desc, hdr->ctr->pac.type_10, + ps, depth)) + return False; + break; + default: /* dont' know, so we need to skip it */ DEBUG(3, ("unknown PAC type %d\n", hdr->type)); -- cgit From f7792732e66b7fc9a6ef4a07ea35b3a2e50f3f69 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 15 Apr 2003 17:06:51 +0000 Subject: Change variable name to get this working on gcc 3.2 (Merge from HEAD) (This used to be commit d49113caef6057905f0f5233ea3085ca5722e742) --- source3/libads/ldap.c | 66 ++++++++++++++++++++++----------------------- source3/libads/ldap_utils.c | 10 +++---- 2 files changed, 38 insertions(+), 38 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 67827d27f3..baedfb28db 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -401,7 +401,7 @@ static char **ads_pull_strvals(TALLOC_CTX *ctx, const char **in_vals) * @param ads connection to ads server * @param bind_path Base dn for the search * @param scope Scope of search (LDAP_BASE | LDAP_ONE | LDAP_SUBTREE) - * @param exp Search expression - specified in local charset + * @param expr Search expression - specified in local charset * @param attrs Attributes to retrieve - specified in utf8 or ascii * @param res ** which will contain results - free res* with ads_msgfree() * @param count Number of entries retrieved on this page @@ -409,12 +409,12 @@ static char **ads_pull_strvals(TALLOC_CTX *ctx, const char **in_vals) * @return status of search **/ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, - int scope, const char *exp, + int scope, const char *expr, const char **attrs, void **res, int *count, void **cookie) { int rc, i, version; - char *utf8_exp, *utf8_path, **search_attrs; + char *utf8_expr, *utf8_path, **search_attrs; LDAPControl PagedResults, NoReferrals, *controls[3], **rcontrols; BerElement *cookie_be = NULL; struct berval *cookie_bv= NULL; @@ -428,7 +428,7 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, /* 0 means the conversion worked but the result was empty so we only fail if it's -1. In any case, it always at least nulls out the dest */ - if ((push_utf8_talloc(ctx, &utf8_exp, exp) == (size_t)-1) || + if ((push_utf8_talloc(ctx, &utf8_expr, expr) == (size_t)-1) || (push_utf8_talloc(ctx, &utf8_path, bind_path) == (size_t)-1)) { rc = LDAP_NO_MEMORY; goto done; @@ -489,7 +489,7 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, */ ldap_set_option(ads->ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF); - rc = ldap_search_ext_s(ads->ld, utf8_path, scope, utf8_exp, + rc = ldap_search_ext_s(ads->ld, utf8_path, scope, utf8_expr, search_attrs, 0, controls, NULL, NULL, LDAP_NO_LIMIT, (LDAPMessage **)res); @@ -497,7 +497,7 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, ber_bvfree(cookie_bv); if (rc) { - DEBUG(3,("ldap_search_ext_s(%s) -> %s\n", exp, ldap_err2string(rc))); + DEBUG(3,("ldap_search_ext_s(%s) -> %s\n", expr, ldap_err2string(rc))); goto done; } @@ -541,20 +541,20 @@ done: * @param ads connection to ads server * @param bind_path Base dn for the search * @param scope Scope of search (LDAP_BASE | LDAP_ONE | LDAP_SUBTREE) - * @param exp Search expression + * @param expr Search expression * @param attrs Attributes to retrieve * @param res ** which will contain results - free res* with ads_msgfree() * @return status of search **/ ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, - int scope, const char *exp, + int scope, const char *expr, const char **attrs, void **res) { void *cookie = NULL; int count = 0; ADS_STATUS status; - status = ads_do_paged_search(ads, bind_path, scope, exp, attrs, res, + status = ads_do_paged_search(ads, bind_path, scope, expr, attrs, res, &count, &cookie); if (!ADS_ERR_OK(status)) return status; @@ -564,7 +564,7 @@ ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, ADS_STATUS status2; LDAPMessage *msg, *next; - status2 = ads_do_paged_search(ads, bind_path, scope, exp, + status2 = ads_do_paged_search(ads, bind_path, scope, expr, attrs, &res2, &count, &cookie); if (!ADS_ERR_OK(status2)) break; @@ -588,14 +588,14 @@ ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, * @param ads connection to ads server * @param bind_path Base dn for the search * @param scope Scope of search (LDAP_BASE | LDAP_ONE | LDAP_SUBTREE) - * @param exp Search expression - specified in local charset + * @param expr Search expression - specified in local charset * @param attrs Attributes to retrieve - specified in UTF-8 or ascii * @param fn Function which takes attr name, values list, and data_area * @param data_area Pointer which is passed to function on each call * @return status of search **/ ADS_STATUS ads_do_search_all_fn(ADS_STRUCT *ads, const char *bind_path, - int scope, const char *exp, const char **attrs, + int scope, const char *expr, const char **attrs, BOOL(*fn)(char *, void **, void *), void *data_area) { @@ -604,7 +604,7 @@ ADS_STATUS ads_do_search_all_fn(ADS_STRUCT *ads, const char *bind_path, ADS_STATUS status; void *res; - status = ads_do_paged_search(ads, bind_path, scope, exp, attrs, &res, + status = ads_do_paged_search(ads, bind_path, scope, expr, attrs, &res, &count, &cookie); if (!ADS_ERR_OK(status)) return status; @@ -613,7 +613,7 @@ ADS_STATUS ads_do_search_all_fn(ADS_STRUCT *ads, const char *bind_path, ads_msgfree(ads, res); while (cookie) { - status = ads_do_paged_search(ads, bind_path, scope, exp, attrs, + status = ads_do_paged_search(ads, bind_path, scope, expr, attrs, &res, &count, &cookie); if (!ADS_ERR_OK(status)) break; @@ -630,18 +630,18 @@ ADS_STATUS ads_do_search_all_fn(ADS_STRUCT *ads, const char *bind_path, * @param ads connection to ads server * @param bind_path Base dn for the search * @param scope Scope of search (LDAP_BASE | LDAP_ONE | LDAP_SUBTREE) - * @param exp Search expression + * @param expr Search expression * @param attrs Attributes to retrieve * @param res ** which will contain results - free res* with ads_msgfree() * @return status of search **/ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, - const char *exp, + const char *expr, const char **attrs, void **res) { struct timeval timeout; int rc; - char *utf8_exp, *utf8_path, **search_attrs = NULL; + char *utf8_expr, *utf8_path, **search_attrs = NULL; TALLOC_CTX *ctx; if (!(ctx = talloc_init("ads_do_search"))) { @@ -652,7 +652,7 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, /* 0 means the conversion worked but the result was empty so we only fail if it's negative. In any case, it always at least nulls out the dest */ - if ((push_utf8_talloc(ctx, &utf8_exp, exp) == (size_t)-1) || + if ((push_utf8_talloc(ctx, &utf8_expr, expr) == (size_t)-1) || (push_utf8_talloc(ctx, &utf8_path, bind_path) == (size_t)-1)) { DEBUG(1,("ads_do_search: push_utf8_talloc() failed!")); rc = LDAP_NO_MEMORY; @@ -679,7 +679,7 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, /* see the note in ads_do_paged_search - we *must* disable referrals */ ldap_set_option(ads->ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF); - rc = ldap_search_ext_s(ads->ld, utf8_path, scope, utf8_exp, + rc = ldap_search_ext_s(ads->ld, utf8_path, scope, utf8_expr, search_attrs, 0, NULL, NULL, &timeout, LDAP_NO_LIMIT, (LDAPMessage **)res); @@ -698,16 +698,16 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, * Do a general ADS search * @param ads connection to ads server * @param res ** which will contain results - free res* with ads_msgfree() - * @param exp Search expression + * @param expr Search expression * @param attrs Attributes to retrieve * @return status of search **/ ADS_STATUS ads_search(ADS_STRUCT *ads, void **res, - const char *exp, + const char *expr, const char **attrs) { return ads_do_search(ads, ads->config.bind_path, LDAP_SCOPE_SUBTREE, - exp, attrs, res); + expr, attrs, res); } /** @@ -772,18 +772,18 @@ char *ads_get_dn(ADS_STRUCT *ads, void *res) ADS_STATUS ads_find_machine_acct(ADS_STRUCT *ads, void **res, const char *host) { ADS_STATUS status; - char *exp; + char *expr; const char *attrs[] = {"*", "nTSecurityDescriptor", NULL}; /* the easiest way to find a machine account anywhere in the tree is to look for hostname$ */ - if (asprintf(&exp, "(samAccountName=%s$)", host) == -1) { + if (asprintf(&expr, "(samAccountName=%s$)", host) == -1) { DEBUG(1, ("asprintf failed!\n")); return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); } - status = ads_search(ads, res, exp, attrs); - free(exp); + status = ads_search(ads, res, expr, attrs); + free(expr); return status; } @@ -1424,7 +1424,7 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) { const char *attrs[] = {"nTSecurityDescriptor", "objectSid", 0}; - char *exp = 0; + char *expr = 0; size_t sd_size = 0; struct berval bval = {0, NULL}; prs_struct ps_wire; @@ -1452,7 +1452,7 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); } - if (asprintf(&exp, "(samAccountName=%s$)", escaped_hostname) == -1) { + if (asprintf(&expr, "(samAccountName=%s$)", escaped_hostname) == -1) { DEBUG(1, ("ads_set_machine_sd: asprintf failed!\n")); SAFE_FREE(escaped_hostname); return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); @@ -1460,7 +1460,7 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) SAFE_FREE(escaped_hostname); - ret = ads_search(ads, (void *) &res, exp, attrs); + ret = ads_search(ads, (void *) &res, expr, attrs); if (!ADS_ERR_OK(ret)) return ret; @@ -2036,7 +2036,7 @@ but you need to force the bind path to match the configurationNamingContext from */ ADS_STATUS ads_workgroup_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char **workgroup) { - char *exp; + char *expr; ADS_STATUS rc; char **principles; char *prefix; @@ -2047,10 +2047,10 @@ ADS_STATUS ads_workgroup_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char **workg (*workgroup) = NULL; - asprintf(&exp, "(&(objectclass=computer)(dnshostname=%s.%s))", + asprintf(&expr, "(&(objectclass=computer)(dnshostname=%s.%s))", ads->config.ldap_server_name, ads->config.realm); - rc = ads_search(ads, &res, exp, attrs); - free(exp); + rc = ads_search(ads, &res, expr, attrs); + free(expr); if (!ADS_ERR_OK(rc)) { return rc; diff --git a/source3/libads/ldap_utils.c b/source3/libads/ldap_utils.c index 907f7c8aff..6855600288 100644 --- a/source3/libads/ldap_utils.c +++ b/source3/libads/ldap_utils.c @@ -28,7 +28,7 @@ this is supposed to catch dropped connections and auto-reconnect */ ADS_STATUS ads_do_search_retry(ADS_STRUCT *ads, const char *bind_path, int scope, - const char *exp, + const char *expr, const char **attrs, void **res) { ADS_STATUS status; @@ -46,10 +46,10 @@ ADS_STATUS ads_do_search_retry(ADS_STRUCT *ads, const char *bind_path, int scope return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); while (count--) { - status = ads_do_search_all(ads, bp, scope, exp, attrs, res); + status = ads_do_search_all(ads, bp, scope, expr, attrs, res); if (ADS_ERR_OK(status)) { DEBUG(5,("Search for %s gave %d replies\n", - exp, ads_count_replies(ads, *res))); + expr, ads_count_replies(ads, *res))); free(bp); return status; } @@ -79,11 +79,11 @@ ADS_STATUS ads_do_search_retry(ADS_STRUCT *ads, const char *bind_path, int scope ADS_STATUS ads_search_retry(ADS_STRUCT *ads, void **res, - const char *exp, + const char *expr, const char **attrs) { return ads_do_search_retry(ads, ads->config.bind_path, LDAP_SCOPE_SUBTREE, - exp, attrs, res); + expr, attrs, res); } ADS_STATUS ads_search_retry_dn(ADS_STRUCT *ads, void **res, -- cgit From bdaac40746567bdadae1150412cdf307b6e8672d Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Wed, 16 Apr 2003 16:57:01 +0000 Subject: Move PAC decoding over from HEAD. (This used to be commit b0fd4e5555dd93c584cd86eaac080663b9e4031f) --- source3/libads/kerberos_verify.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 4d9a1bf765..6a50137400 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -148,6 +148,12 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, get_auth_data_from_tkt(auth_data, tkt); + { + TALLOC_CTX *ctx = talloc_init("pac data"); + decode_pac_data(auth_data, ctx); + talloc_destroy(ctx); + } + #if 0 if (tkt->enc_part2) { file_save("/tmp/authdata.dat", -- cgit From 06c99d15e217e265d51778268d5b859dff3c478c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 21 Apr 2003 13:10:35 +0000 Subject: Add const, static and fix a double free() (merge from HEAD). (This used to be commit 9ba88c7314168b87b72a7e9dc3c7588dcce86893) --- source3/libads/krb5_setpw.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index a5b9eee4ce..214871b3fb 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -538,7 +538,6 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char krb5_free_creds(context, credsp); krb5_free_principal(context, creds.client); - krb5_free_principal(context, creds.server); krb5_free_principal(context, principal); krb5_free_context(context); @@ -571,11 +570,11 @@ kerb_prompter(krb5_context ctx, void *data, return 0; } -ADS_STATUS krb5_chg_password(const char *kdc_host, - const char *principal, - const char *oldpw, - const char *newpw, - int time_offset) +static ADS_STATUS krb5_chg_password(const char *kdc_host, + const char *principal, + const char *oldpw, + const char *newpw, + int time_offset) { ADS_STATUS aret; krb5_error_code ret; -- cgit From f071020f5e49837154581c97c5af5f84d0e2de89 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 21 Apr 2003 14:09:03 +0000 Subject: Merge from HEAD - save the type of channel used to contact the DC. This allows us to join as a BDC, without appearing on the network as one until we have the database replicated, and the admin changes the configuration. This also change the SID retreval order from secrets.tdb, so we no longer require a 'net rpc getsid' - the sid fetch during the domain join is sufficient. Also minor fixes to 'net'. Andrew Bartlett (This used to be commit 876e00fd112e4aaf7519eec27f382eb99ec7562a) --- source3/libads/kerberos_verify.c | 2 +- source3/libads/ldap.c | 8 +++++--- source3/libads/util.c | 8 +++++--- 3 files changed, 11 insertions(+), 7 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 6a50137400..35d429ca2a 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -53,7 +53,7 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, return NT_STATUS_LOGON_FAILURE; } - password_s = secrets_fetch_machine_password(); + password_s = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL); if (!password_s) { DEBUG(1,("failed to fetch machine password\n")); return NT_STATUS_LOGON_FAILURE; diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index baedfb28db..3ce80975da 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1024,6 +1024,7 @@ char *ads_ou_string(const char *org_unit) add a machine account to the ADS server */ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, + uint32 account_type, const char *org_unit) { ADS_STATUS ret, status; @@ -1073,7 +1074,7 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, if (!(samAccountName = talloc_asprintf(ctx, "%s$", hostname))) goto done; - acct_control = UF_WORKSTATION_TRUST_ACCOUNT | UF_DONT_EXPIRE_PASSWD; + acct_control = account_type | UF_DONT_EXPIRE_PASSWD; #ifndef ENCTYPE_ARCFOUR_HMAC acct_control |= UF_USE_DES_KEY_ONLY; #endif @@ -1335,7 +1336,8 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) * @param org_unit Organizational unit to place machine in * @return status of join **/ -ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *hostname, const char *org_unit) +ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *hostname, + uint32 account_type, const char *org_unit) { ADS_STATUS status; LDAPMessage *res; @@ -1356,7 +1358,7 @@ ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *hostname, const char *org } } - status = ads_add_machine_acct(ads, host, org_unit); + status = ads_add_machine_acct(ads, host, account_type, org_unit); if (!ADS_ERR_OK(status)) { DEBUG(0, ("ads_add_machine_acct: %s\n", ads_errstr(status))); return status; diff --git a/source3/libads/util.c b/source3/libads/util.c index 335cabc952..9912a7ba83 100644 --- a/source3/libads/util.c +++ b/source3/libads/util.c @@ -29,21 +29,23 @@ ADS_STATUS ads_change_trust_account_password(ADS_STRUCT *ads, char *host_princip char *new_password; char *service_principal; ADS_STATUS ret; - - if ((password = secrets_fetch_machine_password()) == NULL) { + uint32 sec_channel_type; + + if ((password = secrets_fetch_machine_password(lp_workgroup(), NULL, &sec_channel_type)) == NULL) { DEBUG(1,("Failed to retrieve password for principal %s\n", host_principal)); return ADS_ERROR_SYSTEM(ENOENT); } tmp_password = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH); new_password = strdup(tmp_password); + asprintf(&service_principal, "HOST/%s", host_principal); ret = kerberos_set_password(ads->auth.kdc_server, service_principal, password, service_principal, new_password, ads->auth.time_offset); if (!ADS_ERR_OK(ret)) goto failed; - if (!secrets_store_machine_password(new_password)) { + if (!secrets_store_machine_password(new_password, lp_workgroup(), sec_channel_type)) { DEBUG(1,("Failed to save machine password\n")); return ADS_ERROR_SYSTEM(EACCES); } -- cgit From 77ced5915d0b6bc07d0518ca8bd4412f3ae0e30b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 24 Apr 2003 14:02:02 +0000 Subject: Use the kerberos error from ads_kinit_password() in the return value from our SASL code - help in printing a useful error message. Andrew Bartlett (This used to be commit 984321bfab79a1ff20b504e115e94bd6270f0196) --- source3/libads/sasl.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 29d4533a54..078ff826e3 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -192,14 +192,19 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) #ifdef HAVE_KRB5 if (!(ads->auth.flags & ADS_AUTH_DISABLE_KERBEROS) && got_kerberos_mechanism) { + int krb_error; status = ads_sasl_spnego_krb5_bind(ads, principal); if (ADS_ERR_OK(status)) return status; - if (ads_kinit_password(ads) == 0) { + + krb_error = ads_kinit_password(ads); + if (krb_error) { + return ADS_ERROR_KRB5(krb_error); + } else { status = ads_sasl_spnego_krb5_bind(ads, principal); - } - if (ADS_ERR_OK(status)) - return status; + if (ADS_ERR_OK(status)) + return status; + } } #endif -- cgit From 7041e295eb1167ea4d6fe8d947efb20e1e74d15d Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 24 Apr 2003 14:07:13 +0000 Subject: Revert patch - we need to try the NTLMSSP code below... Andrew Bartlett (This used to be commit 317158972ec944742ba47b213999def9abbf7452) --- source3/libads/sasl.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 078ff826e3..29d4533a54 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -192,19 +192,14 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) #ifdef HAVE_KRB5 if (!(ads->auth.flags & ADS_AUTH_DISABLE_KERBEROS) && got_kerberos_mechanism) { - int krb_error; status = ads_sasl_spnego_krb5_bind(ads, principal); if (ADS_ERR_OK(status)) return status; - - krb_error = ads_kinit_password(ads); - if (krb_error) { - return ADS_ERROR_KRB5(krb_error); - } else { + if (ads_kinit_password(ads) == 0) { status = ads_sasl_spnego_krb5_bind(ads, principal); - if (ADS_ERR_OK(status)) - return status; - } + } + if (ADS_ERR_OK(status)) + return status; } #endif -- cgit From 6a19f354e5ff4e0de91783b23a8161769220e844 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 4 May 2003 02:48:11 +0000 Subject: Patch from Ken Cross to allow an ADS domain join with a username of the form user@realm, where realm might not be the realm we are joining. Andrew Bartlett (This used to be commit 00e08efb5cd21bf42be9125d3188efbf9d13b8b7) --- source3/libads/krb5_setpw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 214871b3fb..856809decc 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -677,7 +677,7 @@ ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads, we need to use the '$' form of the name here, as otherwise the server might end up setting the password for a user instead */ - asprintf(&principal, "%s$@%s", host, ads->auth.realm); + asprintf(&principal, "%s$@%s", host, ads->config.realm); status = krb5_set_password(ads->auth.kdc_server, principal, password, ads->auth.time_offset); -- cgit From ec7b079ab3cb701023db7ae35d6df7704c80f9c9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 15 May 2003 19:43:21 +0000 Subject: Patch from Luke Howard to recognise local groups. Jeremy. (This used to be commit d7a23afe14b0d3ad8ecb7d994768705a32055d9a) --- source3/libads/ads_utils.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ads_utils.c b/source3/libads/ads_utils.c index 750940e336..1aad0bed54 100644 --- a/source3/libads/ads_utils.c +++ b/source3/libads/ads_utils.c @@ -126,6 +126,8 @@ enum SID_NAME_USE ads_atype_map(uint32 atype) switch (atype & 0xF0000000) { case ATYPE_GLOBAL_GROUP: return SID_NAME_DOM_GRP; + case ATYPE_SECURITY_LOCAL_GROUP: + return SID_NAME_ALIAS; case ATYPE_ACCOUNT: return SID_NAME_USER; default: -- cgit From 0463fc2d77293f496a4bff8525b8671f7d5b060a Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 30 May 2003 19:51:09 +0000 Subject: Fix bug #137: krb5_set_password is already defined in MIT 1.3 libs, so we wouldn't build. (This used to be commit 0e9836c4e9e71494b10d71a5f3d5f7da2888c5ef) --- source3/libads/krb5_setpw.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 856809decc..ece305f7e8 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -457,8 +457,8 @@ static ADS_STATUS do_krb5_kpasswd_request(krb5_context context, return ADS_SUCCESS; } -ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char *newpw, - int time_offset) +ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ, + const char *newpw, int time_offset) { ADS_STATUS aret; @@ -651,8 +651,8 @@ ADS_STATUS kerberos_set_password(const char *kpasswd_server, return krb5_chg_password(kpasswd_server, target_principal, auth_password, new_password, time_offset); else - return krb5_set_password(kpasswd_server, target_principal, - new_password, time_offset); + return ads_krb5_set_password(kpasswd_server, target_principal, + new_password, time_offset); } @@ -679,7 +679,8 @@ ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads, */ asprintf(&principal, "%s$@%s", host, ads->config.realm); - status = krb5_set_password(ads->auth.kdc_server, principal, password, ads->auth.time_offset); + status = ads_krb5_set_password(ads->auth.kdc_server, principal, + password, ads->auth.time_offset); free(host); free(principal); -- cgit From 1f3b2790766361c8405632a5dfbfa2934ac33436 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 30 May 2003 20:03:18 +0000 Subject: More on bug 137: rename remainder of krb5_xxx functions to not start with krb5_ (This used to be commit 4169de6d8fb1b13de3892ec787886cc1543736a1) --- source3/libads/krb5_setpw.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index ece305f7e8..df749d04d3 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -195,9 +195,9 @@ static const struct kpasswd_errors { {0, NULL} }; -static krb5_error_code krb5_setpw_result_code_string(krb5_context context, - int result_code, - const char **code_string) +static krb5_error_code setpw_result_code_string(krb5_context context, + int result_code, + const char **code_string) { unsigned int idx = 0; @@ -311,7 +311,7 @@ static krb5_error_code parse_setpw_reply(krb5_context context, return 0; else { const char *errstr; - krb5_setpw_result_code_string(context, res_code, &errstr); + setpw_result_code_string(context, res_code, &errstr); DEBUG(1, ("Error changing password: %s\n", errstr)); switch(res_code) { @@ -570,11 +570,11 @@ kerb_prompter(krb5_context ctx, void *data, return 0; } -static ADS_STATUS krb5_chg_password(const char *kdc_host, - const char *principal, - const char *oldpw, - const char *newpw, - int time_offset) +static ADS_STATUS ads_krb5_chg_password(const char *kdc_host, + const char *principal, + const char *oldpw, + const char *newpw, + int time_offset) { ADS_STATUS aret; krb5_error_code ret; @@ -648,8 +648,8 @@ ADS_STATUS kerberos_set_password(const char *kpasswd_server, } if (!strcmp(auth_principal, target_principal)) - return krb5_chg_password(kpasswd_server, target_principal, - auth_password, new_password, time_offset); + return ads_krb5_chg_password(kpasswd_server, target_principal, + auth_password, new_password, time_offset); else return ads_krb5_set_password(kpasswd_server, target_principal, new_password, time_offset); -- cgit From 4f276f969633f3c39e3ffc609b167930ff7fd42c Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 30 May 2003 20:11:34 +0000 Subject: More on bug 137: rename more of krb5_xxx functions to not start with krb5_ (This used to be commit 10f1da3f4a9680a039a2aa26301b97e31c06c38d) --- source3/libads/kerberos_verify.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 35d429ca2a..a262e27526 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -138,7 +138,7 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, *ap_rep = data_blob(packet.data, packet.length); free(packet.data); - krb5_get_smb_session_key(context, auth_context, session_key); + get_krb5_smb_session_key(context, auth_context, session_key); DEBUG(0,("SMB session key (from ticket) follows:\n")); dump_data(0, session_key, 16); -- cgit From adb710d028751530cb3f3a994d8f0085968e1baf Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 6 Jun 2003 10:22:48 +0000 Subject: No matter how special this session key is, it's not worth a level 0. Hide it behind a level 10, with #ifdef DEBUG_PASSWORD instead. Andrew Bartlett (This used to be commit 9d4e327850fb00083241f3e68f866590c44e1823) --- source3/libads/kerberos_verify.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index a262e27526..65b557af57 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -139,8 +139,10 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, free(packet.data); get_krb5_smb_session_key(context, auth_context, session_key); - DEBUG(0,("SMB session key (from ticket) follows:\n")); - dump_data(0, session_key, 16); +#ifdef DEBUG_PASSWORD + DEBUG(10,("SMB session key (from ticket) follows:\n")); + dump_data(10, session_key, 16); +#endif #if 0 file_save("/tmp/ticket.dat", ticket->data, ticket->length); -- cgit From 2cfc19f89939353e81bc0c00c3fe084a68bba20f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jun 2003 03:47:42 +0000 Subject: added an auth flag that indicates if we should be allowed to fallback to NTLMSSP for SASL if krb5 fails. This is important as otherwise the admin may think that a join has succeeeded when kerberos is actually broken. (This used to be commit 23a6ea385c4aea208adf36f039244bee14f56a33) --- source3/libads/sasl.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 29d4533a54..598208b17f 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -198,8 +198,11 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) if (ads_kinit_password(ads) == 0) { status = ads_sasl_spnego_krb5_bind(ads, principal); } - if (ADS_ERR_OK(status)) + /* only fallback to NTLMSSP if allowed */ + if (ADS_ERR_OK(status) || + !(ads->auth.flags & ADS_AUTH_ALLOW_NTLMSSP)) { return status; + } } #endif -- cgit From 61742d1117e12cbb131f9c55ab0a9acbcc1f4d3a Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 13 Jun 2003 04:29:20 +0000 Subject: Fix shadow variable warning. (This used to be commit c22a4074bd2b998339826ba629fe48153639ec18) --- source3/libads/ldap_printer.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index f5cd4f2885..aa5ac15b5d 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -31,7 +31,7 @@ ADS_STATUS ads_find_printer_on_server(ADS_STRUCT *ads, void **res, const char *printer, const char *servername) { ADS_STATUS status; - char *srv_dn, **srv_cn, *exp; + char *srv_dn, **srv_cn, *s; const char *attrs[] = {"*", "nTSecurityDescriptor", NULL}; status = ads_find_machine_acct(ads, res, servername); @@ -44,12 +44,12 @@ ADS_STATUS ads_find_printer_on_server(ADS_STRUCT *ads, void **res, srv_cn = ldap_explode_dn(srv_dn, 1); ads_msgfree(ads, *res); - asprintf(&exp, "(cn=%s-%s)", srv_cn[0], printer); - status = ads_search(ads, res, exp, attrs); + asprintf(&s, "(cn=%s-%s)", srv_cn[0], printer); + status = ads_search(ads, res, s, attrs); ldap_memfree(srv_dn); ldap_value_free(srv_cn); - free(exp); + free(s); return status; } -- cgit From 0a9396dcca1e30fa32fbcde3ee2dce86f586ba4b Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 13 Jun 2003 04:35:53 +0000 Subject: Rename some uuid functions so as not to conflict with system versions. Fixes bug #154. (This used to be commit 986eae40f7669d15dc75aed340e628aa7efafddc) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 3ce80975da..c685ed53ab 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1142,7 +1142,7 @@ static void dump_guid(const char *field, struct berval **values) GUID guid; for (i=0; values[i]; i++) { memcpy(guid.info, values[i]->bv_val, sizeof(guid.info)); - printf("%s: %s\n", field, uuid_string_static(guid)); + printf("%s: %s\n", field, smb_uuid_string_static(guid)); } } -- cgit From ec0303820fa5ec185f8942604ef3d97285374988 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 16 Jun 2003 02:42:00 +0000 Subject: we need to call ads_first_entry() before using a ldap result, otherwise we can segv or return garbage (This used to be commit d1316656b03e2bc85263b65d24977923ee6f39b7) --- source3/libads/ldap.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index c685ed53ab..0a59c4eb8f 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -749,14 +749,15 @@ void ads_memfree(ADS_STRUCT *ads, void *mem) /** * Get a dn from search results * @param ads connection to ads server - * @param res Search results + * @param msg Search result * @return dn string **/ -char *ads_get_dn(ADS_STRUCT *ads, void *res) +char *ads_get_dn(ADS_STRUCT *ads, void *msg) { char *utf8_dn, *unix_dn; - utf8_dn = ldap_get_dn(ads->ld, res); + utf8_dn = ldap_get_dn(ads->ld, msg); + pull_utf8_allocate((void **) &unix_dn, utf8_dn); ldap_memfree(utf8_dn); return unix_dn; @@ -1078,6 +1079,7 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, #ifndef ENCTYPE_ARCFOUR_HMAC acct_control |= UF_USE_DES_KEY_ONLY; #endif + if (!(controlstr = talloc_asprintf(ctx, "%u", acct_control))) goto done; @@ -1384,7 +1386,7 @@ ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *hostname, ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) { ADS_STATUS status; - void *res; + void *res, *msg; char *hostnameDN, *host; int rc; @@ -1398,7 +1400,12 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) return status; } - hostnameDN = ads_get_dn(ads, (LDAPMessage *)res); + msg = ads_first_entry(ads, res); + if (!msg) { + return ADS_ERROR_SYSTEM(ENOENT); + } + + hostnameDN = ads_get_dn(ads, (LDAPMessage *)msg); rc = ldap_delete_s(ads->ld, hostnameDN); ads_memfree(ads, hostnameDN); if (rc != LDAP_SUCCESS) { -- cgit From f36c96d59c79a51610bb5a1fc42ac62bd8d08401 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 23 Jun 2003 19:05:23 +0000 Subject: * s/get_dc_name/rpc_dc_name/g (revert a previous change) * move back to qsort() for sorting IP address in get_dc_list() * remove dc_name_cache in cm_get_dc_name() since it slowed things down more than it helped. I've made a note of where to add in the negative connection cache in the ads code. Will come back to that. * fix rpcclient to use PRINTER_ALL_ACCESS for set printer (instead of MAX_ALLOWED) * only enumerate domain local groups in our domain * simplify ldap search for seqnum in winbindd's rpc backend (This used to be commit f8cab8635b02b205b4031279cedd804c1fb22c5b) --- source3/libads/ldap.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 0a59c4eb8f..0f1f205f9b 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -41,6 +41,9 @@ /* try a connection to a given ldap server, returning True and setting the servers IP in the ads struct if successful + + TODO : add a negative connection cache in here leveraged off of the one + found in the rpc code. --jerry */ static BOOL ads_try_connect(ADS_STRUCT *ads, const char *server, unsigned port) { -- cgit From f51d769dd303027a3dbf46fc89a482933988e866 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 25 Jun 2003 17:41:05 +0000 Subject: large change: *) consolidates the dc location routines again (dns and netbios) get_dc_list() or get_sorted_dc_list() is the authoritative means of locating DC's again. (also inludes a flag to get_dc_list() to define if this should be a DNS only lookup or not) (however, if you set "name resolve order = hosts wins" you could still get DNS queries for domain name IFF ldap_domain2hostlist() fails. The answer? Fix your DNS setup) *) enabled DOMAIN<0x1c> lookups to be funneled through resolve_hosts resulting in a call to ldap_domain2hostlist() if lp_security() == SEC_ADS *) enables name cache for winbind ADS backend *) enable the negative connection cache for winbind ADS backend *) removes some old dead code *) consolidates some duplicate code *) moves the internal_name_resolve() to use an IP/port pair to deal with SRV RR dns replies. The namecache code also supports the IP:port syntax now as well. *) removes 'ads server' and moves the functionality back into 'password server' (which can support "hostname:port" syntax now but works fine with defaults depending on the value of lp_security()) (This used to be commit d7f7fcda425bef380441509734eca33da943c091) --- source3/libads/ads_struct.c | 3 +- source3/libads/ldap.c | 165 +++++++++++++------------------------------- 2 files changed, 48 insertions(+), 120 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index 652bfe31be..dd31439d83 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -94,8 +94,7 @@ ADS_STRUCT *ads_init(const char *realm, ads->server.workgroup = workgroup ? strdup(workgroup) : NULL; ads->server.ldap_server = ldap_server? strdup(ldap_server) : NULL; - /* we need to know if this is a foreign realm to know if we can - use lp_ads_server() */ + /* we need to know if this is a foreign realm */ if (realm && *realm && strcasecmp(lp_realm(), realm) != 0) { ads->server.foreign = 1; } diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 0f1f205f9b..a168f75e98 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -93,133 +93,75 @@ static BOOL ads_try_connect_uri(ADS_STRUCT *ads) return False; } -/* used by the IP comparison function */ -struct ldap_ip { - struct in_addr ip; - unsigned port; -}; - -/* compare 2 ldap IPs by nearness to our interfaces - used in qsort */ -static int ldap_ip_compare(struct ldap_ip *ip1, struct ldap_ip *ip2) -{ - return ip_compare(&ip1->ip, &ip2->ip); -} +/********************************************************************** + Try to find an AD dc using our internal name resolution routines + Try the realm first and then then workgroup name if netbios is not + disabled +**********************************************************************/ -/* try connecting to a ldap server via DNS */ -static BOOL ads_try_dns(ADS_STRUCT *ads) +static BOOL ads_find_dc(ADS_STRUCT *ads) { const char *c_realm; - const char *ptr; - char *realm; - char *list = NULL; - pstring tok; - struct ldap_ip *ip_list; int count, i=0; + struct ip_service *ip_list; + pstring realm; + BOOL got_realm = False; + /* realm */ c_realm = ads->server.realm; if (!c_realm || !*c_realm) { c_realm = lp_realm(); } - if (!c_realm || !*c_realm) { - c_realm = ads->server.workgroup; - } - if (!c_realm || !*c_realm) { - c_realm = lp_workgroup(); - } - if (!c_realm) { - return False; - } - realm = smb_xstrdup(c_realm); + if ( c_realm ) + got_realm = True; - DEBUG(6,("ads_try_dns: looking for realm '%s'\n", realm)); - if (ldap_domain2hostlist(realm, &list) != LDAP_SUCCESS) { - SAFE_FREE(realm); - return False; + +again: + /* we need to try once with the realm name and fallback to the + netbios domain name if we fail (if netbios has not been disabled */ + + if ( !got_realm && !lp_disable_netbios() ) { + c_realm = ads->server.workgroup; + if (!c_realm || !*c_realm) + c_realm = lp_workgroup(); + if (!c_realm) + return False; } + + pstrcpy( realm, c_realm ); - DEBUG(6,("ads_try_dns: ldap realm '%s' host list '%s'\n", realm, list)); - SAFE_FREE(realm); - - count = count_chars(list, ' ') + 1; - ip_list = malloc(count * sizeof(struct ldap_ip)); - if (!ip_list) { - return False; - } + DEBUG(6,("ads_try_dns: looking for %s realm '%s'\n", + (got_realm ? "realm" : "domain"), realm)); - ptr = list; - while (next_token(&ptr, tok, " ", sizeof(tok))) { - unsigned port = LDAP_PORT; - char *p = strchr(tok, ':'); - if (p) { - *p = 0; - port = atoi(p+1); - } - ip_list[i].ip = *interpret_addr2(tok); - ip_list[i].port = port; - if (!is_zero_ip(ip_list[i].ip)) { - i++; + if ( !get_sorted_dc_list(realm, &ip_list, &count, got_realm) ) { + /* fall back to netbios if we can */ + if ( got_realm && !lp_disable_netbios() ) { + got_realm = False; + goto again; } + + return False; } - free(list); - - count = i; - - /* we sort the list of addresses by closeness to our interfaces. This - tries to prevent us using a DC on the other side of the country */ - if (count > 1) { - qsort(ip_list, count, sizeof(struct ldap_ip), - QSORT_CAST ldap_ip_compare); - } - - for (i=0;iserver.workgroup; - BOOL list_ordered; - - if (!workgroup) { - workgroup = lp_workgroup(); - } - - DEBUG(6,("ads_try_netbios: looking for workgroup '%s'\n", workgroup)); - - /* try the PDC first */ - if (get_pdc_ip(workgroup, &pdc_ip)) { - DEBUG(6,("ads_try_netbios: trying server '%s'\n", - inet_ntoa(pdc_ip))); - if (ads_try_connect(ads, inet_ntoa(pdc_ip), LDAP_PORT)) - return True; - } - - /* now any DC, including backups */ - if (get_dc_list(workgroup, &ip_list, &count, &list_ordered)) { - for (i=0;iserver.foreign && - ads_try_connect(ads, lp_ads_server(), LDAP_PORT)) { - goto got_connection; - } - - /* try via DNS */ - if (ads_try_dns(ads)) { - goto got_connection; - } - - /* try via netbios lookups */ - if (!lp_disable_netbios() && ads_try_netbios(ads)) { + if (ads_find_dc(ads)) { goto got_connection; } -- cgit From 72876b79c9b3f0ab3cda6de42d5c8995aadd687e Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 25 Jun 2003 19:00:15 +0000 Subject: * fix typos in a few debug statements * check negative connection cache before ads_try_connect() in ads_find_dc() (This used to be commit 2a76101a3a31f5fca2f444b25e3f0486f7ef406f) --- source3/libads/ldap.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index a168f75e98..60bbef821c 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -130,7 +130,7 @@ again: pstrcpy( realm, c_realm ); - DEBUG(6,("ads_try_dns: looking for %s realm '%s'\n", + DEBUG(6,("ads_find_dc: looking for %s '%s'\n", (got_realm ? "realm" : "domain"), realm)); if ( !get_sorted_dc_list(realm, &ip_list, &count, got_realm) ) { @@ -147,14 +147,20 @@ again: for ( i=0; i Date: Mon, 30 Jun 2003 05:42:15 +0000 Subject: Fix shadow variable warnings. (This used to be commit 5ffb8e0920be2da19ac3f442b9bf56c159011822) --- source3/libads/ads_ldap.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_ldap.c b/source3/libads/ads_ldap.c index 97f12de0f7..dcceaaeb83 100644 --- a/source3/libads/ads_ldap.c +++ b/source3/libads/ads_ldap.c @@ -34,7 +34,7 @@ NTSTATUS ads_name_to_sid(ADS_STRUCT *ads, int count; ADS_STATUS rc; void *res = NULL; - char *exp; + char *ldap_exp; uint32 t; NTSTATUS status = NT_STATUS_UNSUCCESSFUL; char *escaped_name = escape_ldap_string_alloc(name); @@ -45,15 +45,15 @@ NTSTATUS ads_name_to_sid(ADS_STRUCT *ads, goto done; } - if (asprintf(&exp, "(|(sAMAccountName=%s)(userPrincipalName=%s@%s))", + if (asprintf(&ldap_exp, "(|(sAMAccountName=%s)(userPrincipalName=%s@%s))", escaped_name, escaped_name, escaped_realm) == -1) { DEBUG(1,("ads_name_to_sid: asprintf failed!\n")); status = NT_STATUS_NO_MEMORY; goto done; } - rc = ads_search_retry(ads, &res, exp, attrs); - free(exp); + rc = ads_search_retry(ads, &res, ldap_exp, attrs); + free(ldap_exp); if (!ADS_ERR_OK(rc)) { DEBUG(1,("name_to_sid ads_search: %s\n", ads_errstr(rc))); goto done; @@ -102,7 +102,7 @@ NTSTATUS ads_sid_to_name(ADS_STRUCT *ads, "sAMAccountType", NULL}; ADS_STATUS rc; void *msg = NULL; - char *exp = NULL; + char *ldap_exp = NULL; char *sidstr = NULL; uint32 atype; NTSTATUS status = NT_STATUS_UNSUCCESSFUL; @@ -113,13 +113,13 @@ NTSTATUS ads_sid_to_name(ADS_STRUCT *ads, goto done; } - if (asprintf(&exp, "(objectSid=%s)", sidstr) == -1) { + if (asprintf(&ldap_exp, "(objectSid=%s)", sidstr) == -1) { DEBUG(1,("ads_sid_to_name: asprintf failed!\n")); status = NT_STATUS_NO_MEMORY; goto done; } - rc = ads_search_retry(ads, &msg, exp, attrs); + rc = ads_search_retry(ads, &msg, ldap_exp, attrs); if (!ADS_ERR_OK(rc)) { status = ads_ntstatus(rc); DEBUG(1,("ads_sid_to_name ads_search: %s\n", ads_errstr(rc))); @@ -146,7 +146,7 @@ NTSTATUS ads_sid_to_name(ADS_STRUCT *ads, done: if (msg) ads_msgfree(ads, msg); - SAFE_FREE(exp); + SAFE_FREE(ldap_exp); SAFE_FREE(sidstr); return status; -- cgit From 40ece6552de6049ae69312cca3691c29e7379d47 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 3 Jul 2003 04:12:54 +0000 Subject: Fix bug in doxygen comments for ads search functions. (This used to be commit ae6c05ea726da13fc1a18398d1ffe56f34e1edb9) --- source3/libads/ldap.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 60bbef821c..53c71c405a 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -338,7 +338,7 @@ static char **ads_pull_strvals(TALLOC_CTX *ctx, const char **in_vals) * again when the entire search is complete * @param ads connection to ads server * @param bind_path Base dn for the search - * @param scope Scope of search (LDAP_BASE | LDAP_ONE | LDAP_SUBTREE) + * @param scope Scope of search (LDAP_SCOPE_BASE | LDAP_SCOPE_ONE | LDAP_SCOPE_SUBTREE) * @param expr Search expression - specified in local charset * @param attrs Attributes to retrieve - specified in utf8 or ascii * @param res ** which will contain results - free res* with ads_msgfree() @@ -478,7 +478,7 @@ done: * all entries in a large search. * @param ads connection to ads server * @param bind_path Base dn for the search - * @param scope Scope of search (LDAP_BASE | LDAP_ONE | LDAP_SUBTREE) + * @param scope Scope of search (LDAP_SCOPE_BASE | LDAP_SCOPE_ONE | LDAP_SCOPE_SUBTREE) * @param expr Search expression * @param attrs Attributes to retrieve * @param res ** which will contain results - free res* with ads_msgfree() @@ -525,7 +525,7 @@ ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, * runs the function as each page is returned, using ads_process_results() * @param ads connection to ads server * @param bind_path Base dn for the search - * @param scope Scope of search (LDAP_BASE | LDAP_ONE | LDAP_SUBTREE) + * @param scope Scope of search (LDAP_SCOPE_BASE | LDAP_SCOPE_ONE | LDAP_SCOPE_SUBTREE) * @param expr Search expression - specified in local charset * @param attrs Attributes to retrieve - specified in UTF-8 or ascii * @param fn Function which takes attr name, values list, and data_area @@ -567,7 +567,7 @@ ADS_STATUS ads_do_search_all_fn(ADS_STRUCT *ads, const char *bind_path, * Do a search with a timeout. * @param ads connection to ads server * @param bind_path Base dn for the search - * @param scope Scope of search (LDAP_BASE | LDAP_ONE | LDAP_SUBTREE) + * @param scope Scope of search (LDAP_SCOPE_BASE | LDAP_SCOPE_ONE | LDAP_SCOPE_SUBTREE) * @param expr Search expression * @param attrs Attributes to retrieve * @param res ** which will contain results - free res* with ads_msgfree() -- cgit From baf439cd55d79133e2fca598834e362a81a911a4 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 3 Jul 2003 05:08:51 +0000 Subject: Implemented 'net ads printer search' which searches the directory for published printers. At the moment we don't search using any parameters but this can be fixed by changing the LDAP search string. Also we should contact the global catalog at SRV _gc._tcp instead of the ldap server we get back from ads_startup(). (This used to be commit 814519c5de7f962623163b732c8589abd355d845) --- source3/libads/ldap_printer.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index aa5ac15b5d..b650a5eb38 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -53,6 +53,20 @@ ADS_STATUS ads_find_printer_on_server(ADS_STRUCT *ads, void **res, return status; } +ADS_STATUS ads_find_printers(ADS_STRUCT *ads, void **res) +{ + char *ldap_expr; + const char *attrs[] = { "objectClass", "printerName", "location", "driverName", + "serverName", "description", NULL }; + + /* For the moment only display all printers */ + + ldap_expr = "(&(!(showInAdvancedViewOnly=TRUE))(uncName=*)" + "(objectCategory=printQueue))"; + + return ads_search(ads, res, ldap_expr, attrs); +} + /* modify a printer entry in the directory */ @@ -338,4 +352,3 @@ BOOL get_local_printer_publishing_data(TALLOC_CTX *mem_ctx, } #endif - -- cgit From ce72beb2b558d86fb49063c6b1fa00e07952ce56 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 3 Jul 2003 19:11:31 +0000 Subject: Removed strupper/strlower macros that automatically map to strupper_m/strlower_m. I really want people to think about when they're using multibyte strings. Jeremy. (This used to be commit ff222716a08af65d26ad842ce4c2841cc6540959) --- source3/libads/kerberos_verify.c | 2 +- source3/libads/krb5_setpw.c | 2 +- source3/libads/ldap.c | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 65b557af57..2f4d94f782 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -84,7 +84,7 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, } fstrcpy(myname, global_myname()); - strlower(myname); + strlower_m(myname); asprintf(&host_princ_s, "HOST/%s@%s", myname, lp_realm()); ret = krb5_parse_name(context, host_princ_s, &host_princ); if (ret) { diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index df749d04d3..80ef6cdf01 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -671,7 +671,7 @@ ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads, char *host = strdup(hostname); char *principal; - strlower(host); + strlower_m(host); /* we need to use the '$' form of the name here, as otherwise the diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 53c71c405a..1886b525d9 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -216,7 +216,7 @@ got_connection: /* by default use the machine account */ fstring myname; fstrcpy(myname, global_myname()); - strlower(myname); + strlower_m(myname); asprintf(&ads->auth.user_name, "HOST/%s", myname); } @@ -997,13 +997,13 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, psp = talloc_asprintf(ctx, "HOST/%s.%s", hostname, ads->config.realm); - strlower(&psp[5]); + strlower_m(&psp[5]); servicePrincipalName[1] = psp; servicePrincipalName[2] = talloc_asprintf(ctx, "CIFS/%s", hostname); psp2 = talloc_asprintf(ctx, "CIFS/%s.%s", hostname, ads->config.realm); - strlower(&psp2[5]); + strlower_m(&psp2[5]); servicePrincipalName[3] = psp2; free(ou_str); @@ -1285,7 +1285,7 @@ ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *hostname, /* hostname must be lowercase */ host = strdup(hostname); - strlower(host); + strlower_m(host); status = ads_find_machine_acct(ads, (void **)&res, host); if (ADS_ERR_OK(status) && ads_count_replies(ads, res) == 1) { @@ -1330,7 +1330,7 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) /* hostname must be lowercase */ host = strdup(hostname); - strlower(host); + strlower_m(host); status = ads_find_machine_acct(ads, &res, host); if (!ADS_ERR_OK(status)) { -- cgit From b5cd4a8643169b276a3af8a9272d212d76a54dd3 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 7 Jul 2003 02:50:09 +0000 Subject: Call the synchronous version of the ldap delete function otherwise we end up treating the returned message id as an error code. (This used to be commit 42fdcef324d7a04e69c0078482e1a6b8a67ade94) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 1886b525d9..92f7f7645a 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -937,7 +937,7 @@ ADS_STATUS ads_del_dn(ADS_STRUCT *ads, char *del_dn) return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); } - ret = ldap_delete(ads->ld, utf8_dn); + ret = ldap_delete_s(ads->ld, utf8_dn); return ADS_ERROR(ret); } -- cgit From 62c48a7dbb1161bd074c05afbe2a5260405cd87a Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 10 Jul 2003 08:27:55 +0000 Subject: Fix shadow parameter warning. (This used to be commit 8d8d85ecd62dba075d90e54ec75da9b1328784fb) --- source3/libads/ldap_user.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap_user.c b/source3/libads/ldap_user.c index 7efe5338f3..e70249dd78 100644 --- a/source3/libads/ldap_user.c +++ b/source3/libads/ldap_user.c @@ -28,16 +28,16 @@ ADS_STATUS ads_find_user_acct(ADS_STRUCT *ads, void **res, const char *user) { ADS_STATUS status; - char *exp; + char *ldap_exp; const char *attrs[] = {"*", NULL}; char *escaped_user = escape_ldap_string_alloc(user); if (!escaped_user) { return ADS_ERROR(LDAP_NO_MEMORY); } - asprintf(&exp, "(samAccountName=%s)", escaped_user); - status = ads_search(ads, res, exp, attrs); - SAFE_FREE(exp); + asprintf(&ldap_exp, "(samAccountName=%s)", escaped_user); + status = ads_search(ads, res, ldap_exp, attrs); + SAFE_FREE(ldap_exp); SAFE_FREE(escaped_user); return status; } -- cgit From 9c15a65dc30894bae29dfea3af29beb5caf35883 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 12 Jul 2003 00:27:22 +0000 Subject: Fixed memory leaks, added krb5 replay cache. Now I need to add code to check the incoming addresses.... Jeremy. (This used to be commit 4e9359a1f67a44b2981579383327ba774e1c31f9) --- source3/libads/kerberos_verify.c | 89 ++++++++++++++++++++++++++++++++-------- 1 file changed, 72 insertions(+), 17 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 2f4d94f782..25b7f9d948 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -33,21 +33,32 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, DATA_BLOB *ap_rep, uint8 session_key[16]) { - krb5_context context; + NTSTATUS sret = NT_STATUS_LOGON_FAILURE; + krb5_context context = NULL; krb5_auth_context auth_context = NULL; krb5_keytab keytab = NULL; krb5_data packet; krb5_ticket *tkt = NULL; + krb5_rcache rcache = NULL; int ret, i; - krb5_keyblock * key; + krb5_keyblock *key = NULL; krb5_principal host_princ; - char *host_princ_s; + char *host_princ_s = NULL; fstring myname; - char *password_s; + char *password_s = NULL; krb5_data password; krb5_enctype *enctypes = NULL; +#if 0 + krb5_address local_addr; + krb5_address remote_addr; +#endif BOOL auth_ok = False; + ZERO_STRUCT(packet); + ZERO_STRUCT(password); + ZERO_STRUCTP(auth_data); + ZERO_STRUCTP(ap_rep); + if (!secrets_init()) { DEBUG(1,("secrets_init failed\n")); return NT_STATUS_LOGON_FAILURE; @@ -71,16 +82,19 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, ret = krb5_set_default_realm(context, ads->auth.realm); if (ret) { DEBUG(1,("krb5_set_default_realm failed (%s)\n", error_message(ret))); - return NT_STATUS_LOGON_FAILURE; + sret = NT_STATUS_LOGON_FAILURE; + goto out; } - /* this whole process is far more complex than I would + /* This whole process is far more complex than I would like. We have to go through all this to allow us to store the secret internally, instead of using /etc/krb5.keytab */ + ret = krb5_auth_con_init(context, &auth_context); if (ret) { DEBUG(1,("krb5_auth_con_init failed (%s)\n", error_message(ret))); - return NT_STATUS_LOGON_FAILURE; + sret = NT_STATUS_LOGON_FAILURE; + goto out; } fstrcpy(myname, global_myname()); @@ -89,17 +103,42 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, ret = krb5_parse_name(context, host_princ_s, &host_princ); if (ret) { DEBUG(1,("krb5_parse_name(%s) failed (%s)\n", host_princ_s, error_message(ret))); - return NT_STATUS_LOGON_FAILURE; + sret = NT_STATUS_LOGON_FAILURE; + goto out; + } + + /* + * JRA. We must set the rcache and the allowed addresses in the auth_context + * here. This will prevent replay attacks and ensure the client has got a key from + * the correct IP address. + */ + + ret = krb5_get_server_rcache(context, krb5_princ_component(context, host_princ, 0), &rcache); + if (ret) { + DEBUG(1,("krb5_get_server_rcache failed (%s)\n", error_message(ret))); + sret = NT_STATUS_LOGON_FAILURE; + goto out; + } + + ret = krb5_auth_con_setrcache(context, auth_context, rcache); + if (ret) { + DEBUG(1,("krb5_auth_con_setrcache failed (%s)\n", error_message(ret))); + sret = NT_STATUS_LOGON_FAILURE; + goto out; } + /* Now we need to add the addresses.... JRA. */ + if (!(key = (krb5_keyblock *)malloc(sizeof(*key)))) { - return NT_STATUS_NO_MEMORY; + sret = NT_STATUS_NO_MEMORY; + goto out; } if ((ret = get_kerberos_allowed_etypes(context, &enctypes))) { DEBUG(1,("krb5_get_permitted_enctypes failed (%s)\n", error_message(ret))); - return NT_STATUS_LOGON_FAILURE; + sret = NT_STATUS_LOGON_FAILURE; + goto out; } /* we need to setup a auth context with each possible encoding type in turn */ @@ -124,15 +163,16 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, if (!auth_ok) { DEBUG(3,("krb5_rd_req with auth failed (%s)\n", error_message(ret))); - return NT_STATUS_LOGON_FAILURE; + sret = NT_STATUS_LOGON_FAILURE; + goto out; } ret = krb5_mk_rep(context, auth_context, &packet); if (ret) { DEBUG(3,("Failed to generate mutual authentication reply (%s)\n", error_message(ret))); - krb5_auth_con_free(context, auth_context); - return NT_STATUS_LOGON_FAILURE; + sret = NT_STATUS_LOGON_FAILURE; + goto out; } *ap_rep = data_blob(packet.data, packet.length); @@ -167,15 +207,30 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, principal))) { DEBUG(3,("krb5_unparse_name failed (%s)\n", error_message(ret))); + sret = NT_STATUS_LOGON_FAILURE; + goto out; + } + + sret = NT_STATUS_OK; + + out: + + if (!NT_STATUS_IS_OK(sret)) data_blob_free(auth_data); + + if (!NT_STATUS_IS_OK(sret)) data_blob_free(ap_rep); + + SAFE_FREE(host_princ_s); + SAFE_FREE(password_s); + + if (auth_context) krb5_auth_con_free(context, auth_context); - return NT_STATUS_LOGON_FAILURE; - } - krb5_auth_con_free(context, auth_context); + if (context) + krb5_free_context(context); - return NT_STATUS_OK; + return sret; } #endif /* HAVE_KRB5 */ -- cgit From 3a00cedc0107730876f5bb7626db31d253f9df8b Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 23 Jul 2003 19:58:01 +0000 Subject: connect to the right realm or domain for trusted AD domains (This used to be commit 83376671c511be4bb10d3fca8e49e5f6ef792b9c) --- source3/libads/ldap.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 92f7f7645a..cf6f9375f8 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -109,12 +109,8 @@ static BOOL ads_find_dc(ADS_STRUCT *ads) /* realm */ c_realm = ads->server.realm; - if (!c_realm || !*c_realm) { - c_realm = lp_realm(); - } - if ( c_realm ) + if (c_realm && *c_realm) got_realm = True; - again: /* we need to try once with the realm name and fallback to the @@ -122,10 +118,10 @@ again: if ( !got_realm && !lp_disable_netbios() ) { c_realm = ads->server.workgroup; - if (!c_realm || !*c_realm) - c_realm = lp_workgroup(); - if (!c_realm) + if (!c_realm || !*c_realm) { + DEBUG(0,("ads_find_dc: no realm or workgroup! Was the structure initialized?\n")); return False; + } } pstrcpy( realm, c_realm ); -- cgit From c916e5e390ef3ca9577c2f1d3d58fdad6eec7748 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 25 Jul 2003 16:42:34 +0000 Subject: fix case where no realm or workgroup means to use our own (This used to be commit 6edc7e0a744a5d8c6332758b800a2646ef16dd77) --- source3/libads/ldap.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index cf6f9375f8..62520d5001 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -106,12 +106,24 @@ static BOOL ads_find_dc(ADS_STRUCT *ads) struct ip_service *ip_list; pstring realm; BOOL got_realm = False; + BOOL use_own_domain = False; + + /* if the realm and workgroup are both empty, assume they are ours */ /* realm */ c_realm = ads->server.realm; + + if ( !c_realm || !*c_realm ) { + /* special case where no realm and no workgroup means our own */ + if ( !ads->server.workgroup || !*ads->server.workgroup ) { + use_own_domain = True; + c_realm = lp_realm(); + } + } + if (c_realm && *c_realm) got_realm = True; - + again: /* we need to try once with the realm name and fallback to the netbios domain name if we fail (if netbios has not been disabled */ @@ -119,7 +131,12 @@ again: if ( !got_realm && !lp_disable_netbios() ) { c_realm = ads->server.workgroup; if (!c_realm || !*c_realm) { - DEBUG(0,("ads_find_dc: no realm or workgroup! Was the structure initialized?\n")); + if ( use_own_domain ) + c_realm = lp_workgroup(); + } + + if ( !c_realm || !*c_realm ) { + DEBUG(0,("ads_find_dc: no realm or workgroup! Don't know what to do\n")); return False; } } -- cgit From 4632786cfb193dd80ce04206912297186e871814 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 25 Jul 2003 23:15:30 +0000 Subject: W00t! Client smb signing is now working correctly with krb5 and w2k server. Server code *should* also work (I'll check shortly). May be the odd memory leak. Problem was we (a) weren't setting signing on in the client krb5 sessionsetup code (b) we need to ask for a subkey... (c). The client and server need to ask for local and remote subkeys respectively. Thanks to Paul Nelson @ Thursby for some sage advice on this :-). Jeremy. (This used to be commit 3f9e3b60709df5ab755045a093e642510d4cde00) --- source3/libads/kerberos_verify.c | 2 +- source3/libads/sasl.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 25b7f9d948..4098b44c39 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -178,7 +178,7 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, *ap_rep = data_blob(packet.data, packet.length); free(packet.data); - get_krb5_smb_session_key(context, auth_context, session_key); + get_krb5_smb_session_key(context, auth_context, session_key, True); #ifdef DEBUG_PASSWORD DEBUG(10,("SMB session key (from ticket) follows:\n")); dump_data(10, session_key, 16); diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 598208b17f..910ff3f4dc 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -124,9 +124,10 @@ static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *princip { DATA_BLOB blob; struct berval cred, *scred; + unsigned char sk[16]; int rc; - blob = spnego_gen_negTokenTarg(principal, ads->auth.time_offset); + blob = spnego_gen_negTokenTarg(principal, ads->auth.time_offset, sk); if (!blob.data) { return ADS_ERROR(LDAP_OPERATIONS_ERROR); -- cgit From 05875e573c0f2a27e8d96795dd5a44bacee6275e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 29 Jul 2003 00:31:44 +0000 Subject: Improved debug messages whilst trying to track down kerb issues. Jeremy. (This used to be commit 29dd71ddea480f6163ebbc9d8860a7930ae84066) --- source3/libads/kerberos_verify.c | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 4098b44c39..943df61486 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -60,13 +60,13 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, ZERO_STRUCTP(ap_rep); if (!secrets_init()) { - DEBUG(1,("secrets_init failed\n")); + DEBUG(1,("ads_verify_ticket: secrets_init failed\n")); return NT_STATUS_LOGON_FAILURE; } password_s = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL); if (!password_s) { - DEBUG(1,("failed to fetch machine password\n")); + DEBUG(1,("ads_verify_ticket: failed to fetch machine password\n")); return NT_STATUS_LOGON_FAILURE; } @@ -75,13 +75,13 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, ret = krb5_init_context(&context); if (ret) { - DEBUG(1,("krb5_init_context failed (%s)\n", error_message(ret))); + DEBUG(1,("ads_verify_ticket: krb5_init_context failed (%s)\n", error_message(ret))); return NT_STATUS_LOGON_FAILURE; } ret = krb5_set_default_realm(context, ads->auth.realm); if (ret) { - DEBUG(1,("krb5_set_default_realm failed (%s)\n", error_message(ret))); + DEBUG(1,("ads_verify_ticket: krb5_set_default_realm failed (%s)\n", error_message(ret))); sret = NT_STATUS_LOGON_FAILURE; goto out; } @@ -92,7 +92,7 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, ret = krb5_auth_con_init(context, &auth_context); if (ret) { - DEBUG(1,("krb5_auth_con_init failed (%s)\n", error_message(ret))); + DEBUG(1,("ads_verify_ticket: krb5_auth_con_init failed (%s)\n", error_message(ret))); sret = NT_STATUS_LOGON_FAILURE; goto out; } @@ -102,7 +102,8 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, asprintf(&host_princ_s, "HOST/%s@%s", myname, lp_realm()); ret = krb5_parse_name(context, host_princ_s, &host_princ); if (ret) { - DEBUG(1,("krb5_parse_name(%s) failed (%s)\n", host_princ_s, error_message(ret))); + DEBUG(1,("ads_verify_ticket: krb5_parse_name(%s) failed (%s)\n", + host_princ_s, error_message(ret))); sret = NT_STATUS_LOGON_FAILURE; goto out; } @@ -115,19 +116,19 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, ret = krb5_get_server_rcache(context, krb5_princ_component(context, host_princ, 0), &rcache); if (ret) { - DEBUG(1,("krb5_get_server_rcache failed (%s)\n", error_message(ret))); + DEBUG(1,("ads_verify_ticket: krb5_get_server_rcache failed (%s)\n", error_message(ret))); sret = NT_STATUS_LOGON_FAILURE; goto out; } ret = krb5_auth_con_setrcache(context, auth_context, rcache); if (ret) { - DEBUG(1,("krb5_auth_con_setrcache failed (%s)\n", error_message(ret))); + DEBUG(1,("ads_verify_ticket: krb5_auth_con_setrcache failed (%s)\n", error_message(ret))); sret = NT_STATUS_LOGON_FAILURE; goto out; } - /* Now we need to add the addresses.... JRA. */ + /* CIFS doesn't use addresses in tickets. This would breat NAT. JRA */ if (!(key = (krb5_keyblock *)malloc(sizeof(*key)))) { sret = NT_STATUS_NO_MEMORY; @@ -135,7 +136,7 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, } if ((ret = get_kerberos_allowed_etypes(context, &enctypes))) { - DEBUG(1,("krb5_get_permitted_enctypes failed (%s)\n", + DEBUG(1,("ads_verify_ticket: krb5_get_permitted_enctypes failed (%s)\n", error_message(ret))); sret = NT_STATUS_LOGON_FAILURE; goto out; @@ -154,14 +155,20 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, if (!(ret = krb5_rd_req(context, &auth_context, &packet, NULL, keytab, NULL, &tkt))) { + DEBUG(10,("ads_verify_ticket: enc type [%u] decrypted message !\n", + (unsigned int)enctypes[i] )); free_kerberos_etypes(context, enctypes); auth_ok = True; break; } + + DEBUG((ret != KRB5_KDB_BAD_ENCTYPE) ? 3 : 10, + ("ads_verify_ticket: enc type [%u] failed to decrypt with error %s\n", + (unsigned int)enctypes[i], error_message(ret))); } if (!auth_ok) { - DEBUG(3,("krb5_rd_req with auth failed (%s)\n", + DEBUG(3,("ads_verify_ticket: krb5_rd_req with auth failed (%s)\n", error_message(ret))); sret = NT_STATUS_LOGON_FAILURE; goto out; @@ -169,7 +176,7 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, ret = krb5_mk_rep(context, auth_context, &packet); if (ret) { - DEBUG(3,("Failed to generate mutual authentication reply (%s)\n", + DEBUG(3,("ads_verify_ticket: Failed to generate mutual authentication reply (%s)\n", error_message(ret))); sret = NT_STATUS_LOGON_FAILURE; goto out; @@ -205,7 +212,7 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, if ((ret = krb5_unparse_name(context, get_principal_from_tkt(tkt), principal))) { - DEBUG(3,("krb5_unparse_name failed (%s)\n", + DEBUG(3,("ads_verify_ticket: krb5_unparse_name failed (%s)\n", error_message(ret))); sret = NT_STATUS_LOGON_FAILURE; goto out; -- cgit From 15188bcb02d06881be815e0b98ca16b898d1a9e4 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Tue, 29 Jul 2003 16:34:31 +0000 Subject: Fix the build on Heimdal. KRB5_KDB_BAD_ENCTYPE doesn't exist on Heimdal, and it's a different rc than KRB5_BAD_ENCTYPE (which exists on both MIT and Heimdal). This will just make the debug show up at level 3 always. Jeremy, you may want to revisit this, but it's probably not worth the hassle. (This used to be commit 4ff322ccf9c8485bcfe67e658d48f190f03547b0) --- source3/libads/kerberos_verify.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 943df61486..f9a6c5c97b 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -162,7 +162,7 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, break; } - DEBUG((ret != KRB5_KDB_BAD_ENCTYPE) ? 3 : 10, + DEBUG( 3, ("ads_verify_ticket: enc type [%u] failed to decrypt with error %s\n", (unsigned int)enctypes[i], error_message(ret))); } -- cgit From b40d1a2a765ea919b117476c787716f12fc4c6d6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 29 Jul 2003 17:03:51 +0000 Subject: Typo on my part. I typed KRB5_KDB_BAD_ENCTYPE when I meant to type KRB5_BAD_ENCTYPE. Heimdal has the latter, not the former. Jeremy. (This used to be commit e8425df77c2e917c819592d93833a164ee3b5338) --- source3/libads/kerberos_verify.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index f9a6c5c97b..601e9d0ecd 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -162,7 +162,7 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, break; } - DEBUG( 3, + DEBUG((ret != KRB5_BAD_ENCTYPE) ? 3 : 10, ("ads_verify_ticket: enc type [%u] failed to decrypt with error %s\n", (unsigned int)enctypes[i], error_message(ret))); } -- cgit From 1b89b58475b492b3b60c0cf4f4c8b1d879a80d40 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 29 Jul 2003 21:32:36 +0000 Subject: Put mutex around access of replay cache for krb5 tickets. krb5 replay cache is not multi-process safe. Jeremy. (This used to be commit 9e0534a1b69bbd4f21b4925337cbab127d060fc6) --- source3/libads/kerberos_verify.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 601e9d0ecd..48b61cd1f2 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -109,9 +109,7 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, } /* - * JRA. We must set the rcache and the allowed addresses in the auth_context - * here. This will prevent replay attacks and ensure the client has got a key from - * the correct IP address. + * JRA. We must set the rcache here. This will prevent replay attacks. */ ret = krb5_get_server_rcache(context, krb5_princ_component(context, host_princ, 0), &rcache); @@ -142,7 +140,16 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, goto out; } - /* we need to setup a auth context with each possible encoding type in turn */ + /* Lock a mutex surrounding the replay as there is no locking in the MIT krb5 + * code surrounding the replay cache... */ + + if (!grab_server_mutex("replay cache mutex")) { + DEBUG(1,("ads_verify_ticket: unable to protect replay cache with mutex.\n")); + sret = NT_STATUS_LOGON_FAILURE; + goto out; + } + + /* We need to setup a auth context with each possible encoding type in turn. */ for (i=0;enctypes[i];i++) { if (create_kerberos_key_from_string(context, host_princ, &password, key, enctypes[i])) { continue; @@ -167,6 +174,8 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, (unsigned int)enctypes[i], error_message(ret))); } + release_server_mutex(); + if (!auth_ok) { DEBUG(3,("ads_verify_ticket: krb5_rd_req with auth failed (%s)\n", error_message(ret))); -- cgit From f5799f2db2080633999807cbaccea923f915588d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 30 Jul 2003 15:30:36 +0000 Subject: Comment out mutex until I get dependencies sorted out... Jeremy (This used to be commit 382d1732ca8e4d0909eb5a95f7327213913da37b) --- source3/libads/kerberos_verify.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 48b61cd1f2..779028c7af 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -140,6 +140,7 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, goto out; } +#if 0 /* Lock a mutex surrounding the replay as there is no locking in the MIT krb5 * code surrounding the replay cache... */ @@ -148,6 +149,7 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, sret = NT_STATUS_LOGON_FAILURE; goto out; } +#endif /* We need to setup a auth context with each possible encoding type in turn. */ for (i=0;enctypes[i];i++) { @@ -174,7 +176,9 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, (unsigned int)enctypes[i], error_message(ret))); } +#if 0 release_server_mutex(); +#endif if (!auth_ok) { DEBUG(3,("ads_verify_ticket: krb5_rd_req with auth failed (%s)\n", -- cgit From 316c77ed0b0feaded8d384d3e602842a41d5bb2a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 30 Jul 2003 16:34:14 +0000 Subject: Don't revert something until you've seen if volker has already fixed it :-). Jeremy. (This used to be commit d57d9b99dfc2a83d91b952a11eb1ae4cf37e6467) --- source3/libads/kerberos_verify.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 779028c7af..48b61cd1f2 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -140,7 +140,6 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, goto out; } -#if 0 /* Lock a mutex surrounding the replay as there is no locking in the MIT krb5 * code surrounding the replay cache... */ @@ -149,7 +148,6 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, sret = NT_STATUS_LOGON_FAILURE; goto out; } -#endif /* We need to setup a auth context with each possible encoding type in turn. */ for (i=0;enctypes[i];i++) { @@ -176,9 +174,7 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, (unsigned int)enctypes[i], error_message(ret))); } -#if 0 release_server_mutex(); -#endif if (!auth_ok) { DEBUG(3,("ads_verify_ticket: krb5_rd_req with auth failed (%s)\n", -- cgit From 0d087e3ba28a9061529c95799624ccc4686eb1e9 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 31 Jul 2003 05:43:47 +0000 Subject: working on transtive trusts issue: * use DsEnumerateDomainTrusts() instead of LDAP search. wbinfo -m now lists all trusted downlevel domains and all domains in the forest. Thnigs to do: o Look at Krb5 connection trusted domains o make sure to initial the trusted domain cache as soon as possible (This used to be commit 0ab00ccaedf204b39c86a9e1c2fcac5f15d0e033) --- source3/libads/ldap.c | 71 --------------------------------------------------- 1 file changed, 71 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 62520d5001..dd93502056 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1888,77 +1888,6 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads) return ADS_SUCCESS; } - -/** - * find the list of trusted domains - * @param ads connection to ads server - * @param mem_ctx TALLOC_CTX for allocating results - * @param num_trusts pointer to number of trusts - * @param names pointer to trusted domain name list - * @param sids pointer to list of sids of trusted domains - * @return the count of SIDs pulled - **/ -ADS_STATUS ads_trusted_domains(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, - int *num_trusts, - char ***names, - char ***alt_names, - DOM_SID **sids) -{ - const char *attrs[] = {"name", "flatname", "securityIdentifier", - "trustDirection", NULL}; - ADS_STATUS status; - void *res, *msg; - int count, i; - - *num_trusts = 0; - - status = ads_search(ads, &res, "(objectcategory=trustedDomain)", attrs); - if (!ADS_ERR_OK(status)) return status; - - count = ads_count_replies(ads, res); - if (count == 0) { - ads_msgfree(ads, res); - return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); - } - - (*names) = talloc(mem_ctx, sizeof(char *) * count); - (*alt_names) = talloc(mem_ctx, sizeof(char *) * count); - (*sids) = talloc(mem_ctx, sizeof(DOM_SID) * count); - if (! *names || ! *sids) return ADS_ERROR(LDAP_NO_MEMORY); - - for (i=0, msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) { - uint32 direction; - - /* direction is a 2 bit bitfield, 1 means they trust us - but we don't trust them, so we should not list them - as users from that domain can't login */ - if (ads_pull_uint32(ads, msg, "trustDirection", &direction) && - direction == 1) { - continue; - } - - (*names)[i] = ads_pull_string(ads, mem_ctx, msg, "name"); - (*alt_names)[i] = ads_pull_string(ads, mem_ctx, msg, "flatname"); - - if ((*alt_names)[i] && (*alt_names)[i][0]) { - /* we prefer the flatname as the primary name - for consistency with RPC */ - char *name = (*alt_names)[i]; - (*alt_names)[i] = (*names)[i]; - (*names)[i] = name; - } - if (ads_pull_sid(ads, msg, "securityIdentifier", &(*sids)[i])) { - i++; - } - } - - ads_msgfree(ads, res); - - *num_trusts = i; - - return ADS_SUCCESS; -} - /** * find the domain sid for our domain * @param ads connection to ads server -- cgit From 9f2e6167d22cc06fa94495574fc29d6bcbb1dd8a Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 1 Aug 2003 15:21:20 +0000 Subject: Update my copyrights according to my agreement with IBM (This used to be commit c9b209be2b17c2e4677cc30b46b1074f48878f43) --- source3/libads/authdata.c | 2 +- source3/libads/ldap.c | 2 +- source3/libads/ldap_printer.c | 2 +- source3/libads/ldap_user.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c index c554a02e90..50a9ef2718 100644 --- a/source3/libads/authdata.c +++ b/source3/libads/authdata.c @@ -1,7 +1,7 @@ /* Unix SMB/CIFS implementation. kerberos authorization data (PAC) utility library - Copyright (C) Jim McDonough 2003 + Copyright (C) Jim McDonough 2003 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index dd93502056..5a12288b16 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -3,7 +3,7 @@ ads (active directory) utility library Copyright (C) Andrew Tridgell 2001 Copyright (C) Remus Koos 2001 - Copyright (C) Jim McDonough 2002 + Copyright (C) Jim McDonough 2002 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index b650a5eb38..1448074ea0 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -1,7 +1,7 @@ /* Unix SMB/CIFS implementation. ads (active directory) printer utility library - Copyright (C) Jim McDonough 2002 + Copyright (C) Jim McDonough 2002 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/source3/libads/ldap_user.c b/source3/libads/ldap_user.c index e70249dd78..56a0d8013b 100644 --- a/source3/libads/ldap_user.c +++ b/source3/libads/ldap_user.c @@ -1,7 +1,7 @@ /* Unix SMB/CIFS implementation. ads (active directory) utility library - Copyright (C) Jim McDonough 2002 + Copyright (C) Jim McDonough 2002 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -- cgit From bb6dff2cb1599882ed6142c3617560b6e9755841 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 14 Aug 2003 21:07:49 +0000 Subject: In ads_verify_realm, all we use in the ADS_STRUCT is the auth.realm. So directly pass that instead of setting up and tearing down the ADS_STRUCT. Volker (This used to be commit ce5b8d2ec20fe1f4d3d1956020d88272fb84124a) --- source3/libads/kerberos_verify.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 48b61cd1f2..b82e13b05b 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -28,7 +28,7 @@ verify an incoming ticket and parse out the principal name and authorization_data if available */ -NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, +NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, char **principal, DATA_BLOB *auth_data, DATA_BLOB *ap_rep, uint8 session_key[16]) @@ -79,7 +79,7 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, return NT_STATUS_LOGON_FAILURE; } - ret = krb5_set_default_realm(context, ads->auth.realm); + ret = krb5_set_default_realm(context, realm); if (ret) { DEBUG(1,("ads_verify_ticket: krb5_set_default_realm failed (%s)\n", error_message(ret))); sret = NT_STATUS_LOGON_FAILURE; -- cgit From c9aa836204eb722890cbd4d64248ff7ef1a50e60 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 15 Aug 2003 01:46:09 +0000 Subject: Fix memleaks. Currently I'm compiling against MIT Kerberos 1.2.8. Anthony, you said you have a heimdal installation available. Could you please compile this stuff with krb and check it with valgrind? Thanks, Volker (This used to be commit d8ab44685994b302bb46eed9001c72c194d13dc8) --- source3/libads/authdata.c | 3 +++ source3/libads/kerberos_verify.c | 18 +++++++++++------- 2 files changed, 14 insertions(+), 7 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c index 50a9ef2718..f78a4ad707 100644 --- a/source3/libads/authdata.c +++ b/source3/libads/authdata.c @@ -39,6 +39,7 @@ static DATA_BLOB unwrap_pac(DATA_BLOB *auth_data) asn1_end_tag(&data); asn1_end_tag(&data); asn1_end_tag(&data); + asn1_free(&data); return pac_contents; } @@ -603,6 +604,8 @@ PAC_DATA *decode_pac_data(DATA_BLOB *auth_data, TALLOC_CTX *ctx) prs_copy_data_in(&ps, pac_data_blob.data, pac_data_blob.length); prs_set_offset(&ps, 0); + data_blob_free(&pac_data_blob); + pac_data = (PAC_DATA *) talloc_zero(ctx, sizeof(PAC_DATA)); pac_io_pac_data("pac data", pac_data, &ps, 0); diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index b82e13b05b..3343194203 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -128,11 +128,6 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, /* CIFS doesn't use addresses in tickets. This would breat NAT. JRA */ - if (!(key = (krb5_keyblock *)malloc(sizeof(*key)))) { - sret = NT_STATUS_NO_MEMORY; - goto out; - } - if ((ret = get_kerberos_allowed_etypes(context, &enctypes))) { DEBUG(1,("ads_verify_ticket: krb5_get_permitted_enctypes failed (%s)\n", error_message(ret))); @@ -151,12 +146,19 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, /* We need to setup a auth context with each possible encoding type in turn. */ for (i=0;enctypes[i];i++) { + if (!(key = (krb5_keyblock *)malloc(sizeof(*key)))) { + sret = NT_STATUS_NO_MEMORY; + goto out; + } + if (create_kerberos_key_from_string(context, host_princ, &password, key, enctypes[i])) { continue; } krb5_auth_con_setuseruserkey(context, auth_context, key); + krb5_free_keyblock(context, key); + packet.length = ticket->length; packet.data = (krb5_pointer)ticket->data; @@ -164,7 +166,6 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, NULL, keytab, NULL, &tkt))) { DEBUG(10,("ads_verify_ticket: enc type [%u] decrypted message !\n", (unsigned int)enctypes[i] )); - free_kerberos_etypes(context, enctypes); auth_ok = True; break; } @@ -237,8 +238,11 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, if (!NT_STATUS_IS_OK(sret)) data_blob_free(ap_rep); - SAFE_FREE(host_princ_s); + krb5_free_principal(context, host_princ); + krb5_free_ticket(context, tkt); + free_kerberos_etypes(context, enctypes); SAFE_FREE(password_s); + SAFE_FREE(host_princ_s); if (auth_context) krb5_auth_con_free(context, auth_context); -- cgit From aa39cc37dab9c4f8c3295d872bb8cc143890b378 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Fri, 15 Aug 2003 04:42:05 +0000 Subject: get rid of more compiler warnings (This used to be commit 398bd14fc6e2f8ab2f34211270e179b8928a6669) --- source3/libads/ads_status.c | 2 +- source3/libads/authdata.c | 4 ++-- source3/libads/krb5_setpw.c | 2 +- source3/libads/sasl.c | 16 ++++++++-------- 4 files changed, 12 insertions(+), 12 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_status.c b/source3/libads/ads_status.c index 80fdb99eac..b8f7788bd7 100644 --- a/source3/libads/ads_status.c +++ b/source3/libads/ads_status.c @@ -87,7 +87,7 @@ NTSTATUS ads_ntstatus(ADS_STATUS status) */ const char *ads_errstr(ADS_STATUS status) { - int msg_ctx; + OM_uint32 msg_ctx; static char *ret; SAFE_FREE(ret); diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c index f78a4ad707..29170af377 100644 --- a/source3/libads/authdata.c +++ b/source3/libads/authdata.c @@ -423,7 +423,7 @@ static BOOL pac_io_pac_signature_data(const char *desc, if (!prs_uint32("type", ps, depth, &data->type)) return False; if (UNMARSHALLING(ps)) { - data->signature = prs_alloc_mem(ps, siglen); + data->signature = (unsigned char *)prs_alloc_mem(ps, siglen); if (!data->signature) { DEBUG(3, ("No memory available\n")); return False; @@ -601,7 +601,7 @@ PAC_DATA *decode_pac_data(DATA_BLOB *auth_data, TALLOC_CTX *ctx) DEBUG(5,("dump_pac_data\n")); prs_init(&ps, pac_data_blob.length, ctx, UNMARSHALL); - prs_copy_data_in(&ps, pac_data_blob.data, pac_data_blob.length); + prs_copy_data_in(&ps, (char *)pac_data_blob.data, pac_data_blob.length); prs_set_offset(&ps, 0); data_blob_free(&pac_data_blob); diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 80ef6cdf01..d1da118bb8 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -143,7 +143,7 @@ static krb5_error_code build_kpasswd_request(uint16 pversion, else return EINVAL; - encoded_setpw.data = setpw.data; + encoded_setpw.data = (char *)setpw.data; encoded_setpw.length = setpw.length; ret = krb5_mk_priv(context, auth_context, diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 910ff3f4dc..0320bb0cfc 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -60,7 +60,7 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) msg1 = gen_negTokenTarg(mechs, blob); data_blob_free(&blob); - cred.bv_val = msg1.data; + cred.bv_val = (char *)msg1.data; cred.bv_len = msg1.length; rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred); @@ -106,7 +106,7 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) data_blob_free(&blob); /* now send the auth packet and we should be done */ - cred.bv_val = auth.data; + cred.bv_val = (char *)auth.data; cred.bv_len = auth.length; rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred); @@ -134,7 +134,7 @@ static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *princip } /* now send the auth packet and we should be done */ - cred.bv_val = blob.data; + cred.bv_val = (char *)blob.data; cred.bv_len = blob.length; rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred); @@ -227,7 +227,7 @@ failed: */ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) { - int minor_status; + OM_uint32 minor_status; gss_name_t serv_name; gss_buffer_desc input_name; gss_ctx_id_t context_handle; @@ -328,7 +328,7 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) gss_release_name(&minor_status, &serv_name); gss_rc = gss_unwrap(&minor_status,context_handle,&input_token,&output_token, - &conf_state,NULL); + (int *)&conf_state,NULL); if (gss_rc) { status = ADS_ERROR_GSS(gss_rc, minor_status); goto failed; @@ -353,13 +353,13 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) *p++ = max_msg_size>>16; *p++ = max_msg_size>>8; *p++ = max_msg_size; - snprintf(p, strlen(ads->config.bind_path)+4, "dn:%s", ads->config.bind_path); - p += strlen(p); + snprintf((char *)p, strlen(ads->config.bind_path)+4, "dn:%s", ads->config.bind_path); + p += strlen((const char *)p); output_token.length = PTR_DIFF(p, output_token.value); gss_rc = gss_wrap(&minor_status, context_handle,0,GSS_C_QOP_DEFAULT, - &output_token, &conf_state, + &output_token, (int *)&conf_state, &input_token); if (gss_rc) { status = ADS_ERROR_GSS(gss_rc, minor_status); -- cgit From c904740e95ce416c6ee16171dd8d94cfce43b7d6 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 15 Aug 2003 21:19:34 +0000 Subject: s/OM_uint32//uint32/g (This used to be commit f8a092e7b42cd157cf86240984be40badd0afd87) --- source3/libads/ads_status.c | 2 +- source3/libads/sasl.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_status.c b/source3/libads/ads_status.c index b8f7788bd7..11f9d66b92 100644 --- a/source3/libads/ads_status.c +++ b/source3/libads/ads_status.c @@ -87,7 +87,7 @@ NTSTATUS ads_ntstatus(ADS_STATUS status) */ const char *ads_errstr(ADS_STATUS status) { - OM_uint32 msg_ctx; + uint32 msg_ctx; static char *ret; SAFE_FREE(ret); diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 0320bb0cfc..5122803597 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -227,13 +227,13 @@ failed: */ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) { - OM_uint32 minor_status; + uint32 minor_status; gss_name_t serv_name; gss_buffer_desc input_name; gss_ctx_id_t context_handle; gss_OID mech_type = GSS_C_NULL_OID; gss_buffer_desc output_token, input_token; - OM_uint32 ret_flags, conf_state; + uint32 ret_flags, conf_state; struct berval cred; struct berval *scred; int i=0; -- cgit From 45b9fd9fb935f84a72730addeed6da316a18dfc5 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 15 Aug 2003 21:23:25 +0000 Subject: Don't print out error in ads_do_search_retry() when it suceeds. (This used to be commit 617feab4223f5ba3cc5e090de5e63da72fce49df) --- source3/libads/ldap_utils.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap_utils.c b/source3/libads/ldap_utils.c index 6855600288..1fa9ebfc97 100644 --- a/source3/libads/ldap_utils.c +++ b/source3/libads/ldap_utils.c @@ -73,7 +73,10 @@ ADS_STATUS ads_do_search_retry(ADS_STRUCT *ads, const char *bind_path, int scope } free(bp); - DEBUG(1,("ads reopen failed after error %s\n", ads_errstr(status))); + if (!ADS_ERR_OK(status)) + DEBUG(1,("ads reopen failed after error %s\n", + ads_errstr(status))); + return status; } -- cgit From f1be3a5c5defc2df94550b90b7dd2ed4ab0cb1f2 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 19 Aug 2003 22:47:10 +0000 Subject: - Make 'net' use a single funciton for setting the 'use machine account' code. - Make winbindd try to use kerberos for connections to DCs, so that it can access RA=2 servers, particularly for netlogon. - Make rpcclient follow the new flags for the NETLOGON pipe - Make all the code that uses schannel use the centralised functions for doing so. Andrew Bartlett (This used to be commit 96b4187963cedcfe158ff02868929b8cf81c6ebf) --- source3/libads/krb5_setpw.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index d1da118bb8..9cf15221a8 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -664,25 +664,22 @@ ADS_STATUS kerberos_set_password(const char *kpasswd_server, * @return status of password change **/ ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads, - const char *hostname, + const char *machine_account, const char *password) { ADS_STATUS status; - char *host = strdup(hostname); - char *principal; - - strlower_m(host); + char *principal = NULL; /* - we need to use the '$' form of the name here, as otherwise the - server might end up setting the password for a user instead + we need to use the '$' form of the name here (the machine account name), + as otherwise the server might end up setting the password for a user + instead */ - asprintf(&principal, "%s$@%s", host, ads->config.realm); + asprintf(&principal, "%s@%s", machine_account, ads->config.realm); status = ads_krb5_set_password(ads->auth.kdc_server, principal, password, ads->auth.time_offset); - free(host); free(principal); return status; -- cgit From 8bfe26b62db2e671b143d93a5428f8fb64a9df05 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 20 Aug 2003 17:13:38 +0000 Subject: metze's autogenerate patch for version.h (This used to be commit ae452e51b02672a56adf18aa7a7e365eeaba9272) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 5a12288b16..3de119b5d9 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1045,7 +1045,7 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, ads_mod_str(ctx, &mods, "dNSHostName", hostname); ads_mod_str(ctx, &mods, "userAccountControl", controlstr); ads_mod_str(ctx, &mods, "operatingSystem", "Samba"); - ads_mod_str(ctx, &mods, "operatingSystemVersion", VERSION); + ads_mod_str(ctx, &mods, "operatingSystemVersion", SAMBA_VERSION_STRING); ret = ads_gen_add(ads, new_dn, mods); -- cgit From 51dfb55b8a95453e21a9e4a18f56843a27cdf267 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 25 Aug 2003 09:13:20 +0000 Subject: Fix segfault. krb5_free_ticket does not check if it got a NULL ticket. (This used to be commit 97e4778103744419ecaeb0058460041ef01b2e2a) --- source3/libads/kerberos_verify.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 3343194203..4bd20a3639 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -239,7 +239,8 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, data_blob_free(ap_rep); krb5_free_principal(context, host_princ); - krb5_free_ticket(context, tkt); + if (tkt != NULL) + krb5_free_ticket(context, tkt); free_kerberos_etypes(context, enctypes); SAFE_FREE(password_s); SAFE_FREE(host_princ_s); -- cgit From d517c1d613d7cace619878ca9853b154aa71dec3 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Wed, 3 Sep 2003 00:45:15 +0000 Subject: Try to add memory keytab support. It also includes much of the generic keytab support code, but it won't be enabled until we add that to smb.conf. Adapted from the work of Guenther Deschner (gd@suse.com). Please hammer on this... (This used to be commit a26fa5bee24c73cd835f59bb18162ab07760d76a) --- source3/libads/kerberos_verify.c | 142 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 141 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 4bd20a3639..4ae89aa01f 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -4,6 +4,8 @@ Copyright (C) Andrew Tridgell 2001 Copyright (C) Remus Koos 2001 Copyright (C) Luke Howard 2003 + Copyright (C) Guenther Deschner 2003 + Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -24,6 +26,127 @@ #ifdef HAVE_KRB5 +static void free_keytab(krb5_context context, krb5_keytab keytab) +{ + int ret=0; + + if (keytab) + ret = krb5_kt_close(context, keytab); + if (ret) { + DEBUG(3, ("krb5_kt_close failed (%s)\n", + error_message(ret))); + } +} + +#ifdef HAVE_MEMORY_KEYTAB +static krb5_error_code create_keytab(krb5_context context, + krb5_principal host_princ, + char *host_princ_s, + krb5_data password, + krb5_enctype *enctypes, + krb5_keytab *keytab, + char *keytab_name) +{ + krb5_keytab_entry entry; + krb5_kvno kvno = 1; + krb5_error_code ret; + krb5_keyblock *key; + int i; + + DEBUG(10,("creating keytab: %s\n", keytab_name)); + ret = krb5_kt_resolve(context, keytab_name, keytab); + if (ret) + return ret; + + if (!(key = (krb5_keyblock *)malloc(sizeof(*key)))) { + return ENOMEM; + } + + /* add keytab entries for all encryption types */ + for ( i=0; enctypes[i]; i++ ) { + + if (create_kerberos_key_from_string(context, host_princ, &password, key, enctypes[i])) { + continue; + } + + entry.principal = host_princ; + entry.vno = kvno; + /* this will have to be detected in configure...heimdal + calls it keyblock, MIT calls it key, but it does not + matter we are creating keytabs with MIT */ + entry.keyblock = *key; + + DEBUG(10,("adding keytab-entry for (%s) with encryption type (%d)\n", + host_princ_s, enctypes[i])); + ret = krb5_kt_add_entry(context, *keytab, &entry); + if (ret) { + DEBUG(1,("adding entry to keytab failed (%s)\n", + error_message(ret))); + free_keytab(context, *keytab); + return ret; + } + } + krb5_free_keyblock(context, key); + + return 0; +} +#endif + +static BOOL setup_keytab(krb5_context context, + krb5_principal host_princ, + char *host_princ_s, + krb5_data password, + krb5_enctype *enctypes, + krb5_keytab *keytab) +{ + char *keytab_name = NULL; + krb5_error_code ret; + + /* check if we have to setup a keytab - not currently enabled + I've put this in so that the else block below functions + the same way that it will when this code is turned on */ + if (0 /* will later be *lp_keytab() */) { + + /* use a file-keytab */ + asprintf(&keytab_name, "%s:%s", + "" + /* KRB5_KT_FILE_PREFIX, "FILE" or + "WRFILE" depending on HEeimdal or MIT */, + "" /* will later be lp_keytab() */); + + DEBUG(10,("will use filebased keytab: %s\n", keytab_name)); + ret = krb5_kt_resolve(context, keytab_name, keytab); + if (ret) { + DEBUG(3,("cannot resolve keytab name %s (%s)\n", + keytab_name, + error_message(ret))); + SAFE_FREE(keytab_name); + return False; + } + + } + +#if defined(HAVE_MEMORY_KEYTAB) + else { + + /* setup a in-memory-keytab */ + asprintf(&keytab_name, "MEMORY:"); + + ret = create_keytab(context, host_princ, host_princ_s, password, enctypes, + keytab, keytab_name); + if (ret) { + DEBUG(3,("unable to create MEMORY: keytab (%s)\n", + error_message(ret))); + SAFE_FREE(keytab_name); + return False; + } + } +#endif + SAFE_FREE(keytab_name); + return True; +} + + /* verify an incoming ticket and parse out the principal name and authorization_data if available @@ -144,6 +267,13 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, goto out; } + if (!setup_keytab(context, host_princ, host_princ_s, password, + enctypes, &keytab)) { + DEBUG(3,("ads_verify_ticket: unable to setup keytab\n")); + sret = NT_STATUS_LOGON_FAILURE; + goto out; + } + /* We need to setup a auth context with each possible encoding type in turn. */ for (i=0;enctypes[i];i++) { if (!(key = (krb5_keyblock *)malloc(sizeof(*key)))) { @@ -163,7 +293,12 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, packet.data = (krb5_pointer)ticket->data; if (!(ret = krb5_rd_req(context, &auth_context, &packet, - NULL, keytab, NULL, &tkt))) { +#ifdef HAVE_MEMORY_KEYTAB + host_princ, +#else + NULL, +#endif + keytab, NULL, &tkt))) { DEBUG(10,("ads_verify_ticket: enc type [%u] decrypted message !\n", (unsigned int)enctypes[i] )); auth_ok = True; @@ -218,8 +353,13 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, file_save("/tmp/authdata.dat", tkt->enc_part2->authorization_data[0]->contents, tkt->enc_part2->authorization_data[0]->length); + } #endif + + /* get rid of all resources associated with the keytab */ + if (keytab) free_keytab(context, keytab); + if ((ret = krb5_unparse_name(context, get_principal_from_tkt(tkt), principal))) { DEBUG(3,("ads_verify_ticket: krb5_unparse_name failed (%s)\n", -- cgit From d5bef211d0cee0f0c7fab5c890694cabd408e6e3 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Sat, 6 Sep 2003 18:02:19 +0000 Subject: revert retry loops in winbindd_ads as abartket points out, we already have ads_search_retry() for this. However, neither domain_sid() nor sequence_nunber() used this function. So modify them to us ads_do_search_retry() so we can specify the base search DN and scope. (This used to be commit 89f6adf830187d020bf4b35d1a4b2b48c7a075d0) --- source3/libads/ldap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 3de119b5d9..e925750e0a 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1777,7 +1777,7 @@ ADS_STATUS ads_USN(ADS_STRUCT *ads, uint32 *usn) ADS_STATUS status; void *res; - status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); + status = ads_do_search_retry(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); if (!ADS_ERR_OK(status)) return status; if (ads_count_replies(ads, res) != 1) { @@ -1900,7 +1900,7 @@ ADS_STATUS ads_domain_sid(ADS_STRUCT *ads, DOM_SID *sid) void *res; ADS_STATUS rc; - rc = ads_do_search(ads, ads->config.bind_path, LDAP_SCOPE_BASE, "(objectclass=*)", + rc = ads_do_search_retry(ads, ads->config.bind_path, LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); if (!ADS_ERR_OK(rc)) return rc; if (!ads_pull_sid(ads, res, "objectSid", sid)) { -- cgit From ca1c6ebb11361dabaca22015736f3876d51833a2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 10 Sep 2003 22:33:06 +0000 Subject: Fix a nasty mess, and also bug #296. passdb/pdb_ldap.c was not converting to/from utf8 for some calls. The libads code gets this right. Wonder why the passdb code doesn't use it ? Jeremy. (This used to be commit 910d21d3164c2c64773031fddaad35ea88e72a04) --- source3/libads/ldap.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index e925750e0a..48401cc3d8 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -709,7 +709,16 @@ char *ads_get_dn(ADS_STRUCT *ads, void *msg) utf8_dn = ldap_get_dn(ads->ld, msg); - pull_utf8_allocate((void **) &unix_dn, utf8_dn); + if (!utf8_dn) { + DEBUG (5, ("ads_get_dn: ldap_get_dn failed\n")); + return NULL; + } + + if (pull_utf8_allocate((void **) &unix_dn, utf8_dn) == (size_t)-1) { + DEBUG(0,("ads_get_dn: string conversion failure utf8 [%s]\n", + utf8_dn )); + return NULL; + } ldap_memfree(utf8_dn); return unix_dn; } -- cgit From 48958b0105dce32888497e79106e08c70af7e3ef Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 3 Oct 2003 21:43:09 +0000 Subject: don't call ads_destroy() twice; fixes segfault in winbindd when DC goes down; bug 437 (This used to be commit 1cfbd92404270e0c67a3b295fc9cf461b29d3503) --- source3/libads/ldap.c | 3 ++- source3/libads/ldap_utils.c | 7 ++++++- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 48401cc3d8..8c3185ea5e 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1787,7 +1787,8 @@ ADS_STATUS ads_USN(ADS_STRUCT *ads, uint32 *usn) void *res; status = ads_do_search_retry(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); - if (!ADS_ERR_OK(status)) return status; + if (!ADS_ERR_OK(status)) + return status; if (ads_count_replies(ads, res) != 1) { return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); diff --git a/source3/libads/ldap_utils.c b/source3/libads/ldap_utils.c index 1fa9ebfc97..4142bceabc 100644 --- a/source3/libads/ldap_utils.c +++ b/source3/libads/ldap_utils.c @@ -54,15 +54,20 @@ ADS_STATUS ads_do_search_retry(ADS_STRUCT *ads, const char *bind_path, int scope return status; } - if (*res) ads_msgfree(ads, *res); + if (*res) + ads_msgfree(ads, *res); *res = NULL; + DEBUG(3,("Reopening ads connection to realm '%s' after error %s\n", ads->config.realm, ads_errstr(status))); + if (ads->ld) { ldap_unbind(ads->ld); } + ads->ld = NULL; status = ads_connect(ads); + if (!ADS_ERR_OK(status)) { DEBUG(1,("ads_search_retry: failed to reconnect (%s)\n", ads_errstr(status))); -- cgit From 72b9e5571a0cdb7e4587324f42394e04a2cfa3db Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 17 Oct 2003 04:59:07 +0000 Subject: Add configure test for krb5_keytab_entry keyblock vs key member. Bug #636. (This used to be commit 3daefe9d17fb2c7b1c4d21593465e6788555b0fb) --- source3/libads/kerberos_verify.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 4ae89aa01f..cdea5a2fe4 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -71,10 +71,18 @@ static krb5_error_code create_keytab(krb5_context context, entry.principal = host_princ; entry.vno = kvno; - /* this will have to be detected in configure...heimdal - calls it keyblock, MIT calls it key, but it does not - matter we are creating keytabs with MIT */ - entry.keyblock = *key; + +#if !defined(HAVE_KRB5_KEYTAB_ENTRY_KEY) && !defined(HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK) +#error krb5_keytab_entry has no key or keyblock member +#endif + +#ifdef HAVE_KRB5_KEYTAB_ENTRY_KEY /* MIT */ + entry.key = *key; +#endif + +#ifdef HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK /* Heimdal */ + entry.keyblock = *key; +#endif DEBUG(10,("adding keytab-entry for (%s) with encryption type (%d)\n", host_princ_s, enctypes[i])); -- cgit From bb0598faf58679a7ad26a1caab8eadb154a07ae2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 22 Oct 2003 23:38:20 +0000 Subject: Put strcasecmp/strncasecmp on the banned list (except for needed calls in iconv.c and nsswitch/). Using them means you're not thinking about multibyte at all and I really want to discourage that. Jeremy. (This used to be commit d7e35dfb9283d560d0ed2ab231f36ed92767dace) --- source3/libads/ads_struct.c | 4 ++-- source3/libads/ldap.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index dd31439d83..9774968e12 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -95,10 +95,10 @@ ADS_STRUCT *ads_init(const char *realm, ads->server.ldap_server = ldap_server? strdup(ldap_server) : NULL; /* we need to know if this is a foreign realm */ - if (realm && *realm && strcasecmp(lp_realm(), realm) != 0) { + if (realm && *realm && !strequal(lp_realm(), realm)) { ads->server.foreign = 1; } - if (workgroup && *workgroup && strcasecmp(lp_workgroup(), workgroup) != 0) { + if (workgroup && *workgroup && !strequal(lp_workgroup(), workgroup)) { ads->server.foreign = 1; } diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 8c3185ea5e..b3706cb240 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -972,7 +972,7 @@ ADS_STATUS ads_del_dn(ADS_STRUCT *ads, char *del_dn) **/ char *ads_ou_string(const char *org_unit) { - if (!org_unit || !*org_unit || strcasecmp(org_unit, "Computers") == 0) { + if (!org_unit || !*org_unit || strequal(org_unit, "Computers")) { return strdup("cn=Computers"); } @@ -1970,8 +1970,8 @@ ADS_STATUS ads_workgroup_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char **workg prefix_length = strlen(prefix); for (i=0;principles[i]; i++) { - if (strncasecmp(principles[i], prefix, prefix_length) == 0 && - strcasecmp(ads->config.realm, principles[i]+prefix_length) != 0 && + if (strnequal(principles[i], prefix, prefix_length) && + !strequal(ads->config.realm, principles[i]+prefix_length) && !strchr(principles[i]+prefix_length, '.')) { /* found an alternate (short) name for the domain. */ DEBUG(3,("Found alternate name '%s' for realm '%s'\n", -- cgit From fcbfc7ad0669009957c65fa61bb20df75a9701b4 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 22 Nov 2003 13:19:38 +0000 Subject: Changes all over the shop, but all towards: - NTLM2 support in the server - KEY_EXCH support in the server - variable length session keys. In detail: - NTLM2 is an extension of NTLMv1, that is compatible with existing domain controllers (unlike NTLMv2, which requires a DC upgrade). * This is known as 'NTLMv2 session security' * (This is not yet implemented on the RPC pipes however, so there may well still be issues for PDC setups, particuarly around password changes. We do not fully understand the sign/seal implications of NTLM2 on RPC pipes.) This requires modifications to our authentication subsystem, as we must handle the 'challege' input into the challenge-response algorithm being changed. This also needs to be turned off for 'security=server', which does not support this. - KEY_EXCH is another 'security' mechanism, whereby the session key actually used by the server is sent by the client, rather than being the shared-secret directly or indirectly. - As both these methods change the session key, the auth subsystem needed to be changed, to 'override' session keys provided by the backend. - There has also been a major overhaul of the NTLMSSP subsystem, to merge the 'client' and 'server' functions, so they both operate on a single structure. This should help the SPNEGO implementation. - The 'names blob' in NTLMSSP is always in unicode - never in ascii. Don't make an ascii version ever. - The other big change is to allow variable length session keys. We have always assumed that session keys are 16 bytes long - and padded to this length if shorter. However, Kerberos session keys are 8 bytes long, when the krb5 login uses DES. * This fix allows SMB signging on machines not yet running MIT KRB5 1.3.1. * - Add better DEBUG() messages to ntlm_auth, warning administrators of misconfigurations that prevent access to the privileged pipe. This should help reduce some of the 'it just doesn't work' issues. - Fix data_blob_talloc() to behave the same way data_blob() does when passed a NULL data pointer. (just allocate) REMEMBER to make clean after this commit - I have changed plenty of data structures... (This used to be commit f3bbc87b0dac63426cda6fac7a295d3aad810ecc) --- source3/libads/kerberos_verify.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index cdea5a2fe4..b0efb8f598 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -162,7 +162,7 @@ static BOOL setup_keytab(krb5_context context, NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, char **principal, DATA_BLOB *auth_data, DATA_BLOB *ap_rep, - uint8 session_key[16]) + DATA_BLOB *session_key) { NTSTATUS sret = NT_STATUS_LOGON_FAILURE; krb5_context context = NULL; -- cgit From 203710ea6d74a6ff17ed3c2d718022242384ee3a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 26 Nov 2003 09:58:41 +0000 Subject: Get rid of a const warning Volker (This used to be commit 94860687c535ace0c962ca3fe7da59df05325c62) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index b3706cb240..072f42513c 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1933,7 +1933,7 @@ bin/net -Uadministrator%XXXXX ads search '(&(objectclass=crossref)(dnsroot=VNET3 but you need to force the bind path to match the configurationNamingContext from the rootDSE */ -ADS_STATUS ads_workgroup_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char **workgroup) +ADS_STATUS ads_workgroup_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char **workgroup) { char *expr; ADS_STATUS rc; -- cgit From ec83590024abb0b30a452502285220ceee967bd2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 13 Dec 2003 01:43:54 +0000 Subject: Fix from ndb@theghet.to to allow an existing LDAP machine account to be re-used, rather than created from scratch. Jeremy. (This used to be commit 6d46e66ac2048352ca60f92fc384f60406024d4b) --- source3/libads/ldap.c | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 072f42513c..99227f6574 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -998,6 +998,14 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, const char *servicePrincipalName[5] = {NULL, NULL, NULL, NULL, NULL}; char *psp, *psp2; unsigned acct_control; + unsigned exists=0; + LDAPMessage *res; + + status = ads_find_machine_acct(ads, (void **)&res, hostname); + if (ADS_ERR_OK(status) && ads_count_replies(ads, res) == 1) { + DEBUG(0, ("Host account for %s already exists - modifying old account\n", hostname)); + exists=1; + } if (!(ctx = talloc_init("machine_account"))) return ADS_ERROR(LDAP_NO_MEMORY); @@ -1045,18 +1053,23 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, if (!(mods = ads_init_mods(ctx))) goto done; - - ads_mod_str(ctx, &mods, "cn", hostname); - ads_mod_str(ctx, &mods, "sAMAccountName", samAccountName); - ads_mod_strlist(ctx, &mods, "objectClass", objectClass); + + if (!exists) { + ads_mod_str(ctx, &mods, "cn", hostname); + ads_mod_str(ctx, &mods, "sAMAccountName", samAccountName); + ads_mod_str(ctx, &mods, "userAccountControl", controlstr); + ads_mod_strlist(ctx, &mods, "objectClass", objectClass); + } + ads_mod_str(ctx, &mods, "dNSHostName", hostname); ads_mod_str(ctx, &mods, "userPrincipalName", host_upn); ads_mod_strlist(ctx, &mods, "servicePrincipalName", servicePrincipalName); - ads_mod_str(ctx, &mods, "dNSHostName", hostname); - ads_mod_str(ctx, &mods, "userAccountControl", controlstr); ads_mod_str(ctx, &mods, "operatingSystem", "Samba"); ads_mod_str(ctx, &mods, "operatingSystemVersion", SAMBA_VERSION_STRING); - ret = ads_gen_add(ads, new_dn, mods); + if (!exists) + ret = ads_gen_add(ads, new_dn, mods); + else + ret = ads_gen_mod(ads, new_dn, mods); if (!ADS_ERR_OK(ret)) goto done; @@ -1065,11 +1078,13 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, * it shouldn't be mandatory and probably we just * don't have enough rights to do it. */ - status = ads_set_machine_sd(ads, hostname, new_dn); - - if (!ADS_ERR_OK(status)) { - DEBUG(0, ("Warning: ads_set_machine_sd: %s\n", - ads_errstr(status))); + if (!exists) { + status = ads_set_machine_sd(ads, hostname, new_dn); + + if (!ADS_ERR_OK(status)) { + DEBUG(0, ("Warning: ads_set_machine_sd: %s\n", + ads_errstr(status))); + } } done: talloc_destroy(ctx); @@ -1309,6 +1324,7 @@ ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *hostname, host = strdup(hostname); strlower_m(host); + /* status = ads_find_machine_acct(ads, (void **)&res, host); if (ADS_ERR_OK(status) && ads_count_replies(ads, res) == 1) { DEBUG(0, ("Host account for %s already exists - deleting old account\n", host)); @@ -1319,6 +1335,7 @@ ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *hostname, return status; } } + */ status = ads_add_machine_acct(ads, host, account_type, org_unit); if (!ADS_ERR_OK(status)) { -- cgit From 5eee23cc64139ba1d23101c87709e6d5198a6c68 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 31 Dec 2003 00:31:43 +0000 Subject: auth/auth_util.c: - Fill in the 'backup' idea of a domain, if the DC didn't supply one. This doesn't seem to occour in reality, hence why we missed the typo. lib/charcnv.c: lib/smbldap.c: libads/ldap.c: libsmb/libsmbclient.c: printing/nt_printing.c: - all the callers to pull_utf8_allocate() pass a char ** as the first parammeter, so don't make them all cast it to a void ** nsswitch/winbind_util.c: - Allow for a more 'correct' view of when usernames should be qualified in winbindd. If we are a PDC, or have 'winbind trusted domains only', then for the authentication returns stip the domain portion. - Fix valgrind warning about use of free()ed name when looking up our local domain. lp_workgroup() is maniplated inside a procedure that uses it's former value. Instead, use the fact that our local domain is always the first in the list. Andrew Bartlett (This used to be commit 494781f628683d6e68e8ba21ae54f738727e8c21) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 99227f6574..ce0341b72c 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -714,7 +714,7 @@ char *ads_get_dn(ADS_STRUCT *ads, void *msg) return NULL; } - if (pull_utf8_allocate((void **) &unix_dn, utf8_dn) == (size_t)-1) { + if (pull_utf8_allocate(&unix_dn, utf8_dn) == (size_t)-1) { DEBUG(0,("ads_get_dn: string conversion failure utf8 [%s]\n", utf8_dn )); return NULL; -- cgit From 31ff56fd3ef310c1fab557cf26c65ab96d38fb39 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 1 Jan 2004 20:30:50 +0000 Subject: Fix for bug 707, getent group for huge ads groups (>1500 members) This introduces range retrieval of ADS attributes. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I've rewritten most of Günther's patch, partly to remove code duplication and partly to get the retrieval of members in one rush, not interrupted by the lookups for the DN. Andrew, you told me that you would like to see a check whether the AD sequence number is the same before and after the retrieval to achieve atomicity. This would be trivial to add, but I'm not sure that we want this, as this adds two roundtrips to every membership query. We can not know before the first query whether we get additional range values, and at that point it's too late to ask for the USN. Tested with a group of 4000 members along with lots of small groups. Volker (This used to be commit 9d8235bf413f931e40bca0c27a25ed62b4f3d226) --- source3/libads/ldap.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 92 insertions(+), 8 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index ce0341b72c..f47645c7e7 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1579,27 +1579,26 @@ char *ads_pull_string(ADS_STRUCT *ads, * @return Result strings in talloc context **/ char **ads_pull_strings(ADS_STRUCT *ads, - TALLOC_CTX *mem_ctx, void *msg, const char *field) + TALLOC_CTX *mem_ctx, void *msg, const char *field, + int *num_values) { char **values; char **ret = NULL; - int i, n; + int i; values = ldap_get_values(ads->ld, msg, field); if (!values) return NULL; - for (i=0;values[i];i++) - /* noop */ ; - n = i; + *num_values = ldap_count_values(values); - ret = talloc(mem_ctx, sizeof(char *) * (n+1)); + ret = talloc(mem_ctx, sizeof(char *) * (*num_values+1)); if (!ret) { ldap_value_free(values); return NULL; } - for (i=0;ild, (LDAPMessage *)msg, &ptr); + + if (first_attr == NULL) + return NULL; + + expected_range_attrib = talloc_asprintf(mem_ctx, "%s;Range=", field); + + if (!strequal(first_attr, field) && + !strnequal(first_attr, expected_range_attrib, + strlen(expected_range_attrib))) + { + DEBUG(1, ("Expected attribute [%s], got [%s]\n", + field, first_attr)); + return NULL; + } + + second_attr = ldap_next_attribute(ads->ld, (LDAPMessage *)msg, ptr); + ber_free(ptr, 0); + + DEBUG(10,("attr: [%s], first_attr: [%s], second_attr: [%s]\n", + field, first_attr, second_attr)); + + if ((second_attr != NULL) && + (strnequal(second_attr, expected_range_attrib, + strlen(expected_range_attrib)))) { + + /* This is the first in a row of range results. We can not ask + * for the attribute we wanted, as this is empty in the LDAP + * msg, the delivered values are in the second range-augmented + * attribute. */ + range_attr = second_attr; + + } else { + + /* Upon second and subsequent requests to get attribute + * values, first_attr carries the Range= specifier. */ + range_attr = first_attr; + + } + + /* We have to ask for more if we have a range specifier in the + * attribute and the attribute does not end in "*". */ + + *more_values = ( (strnequal(range_attr, expected_range_attrib, + strlen(expected_range_attrib))) && + (range_attr[strlen(range_attr)-1] != '*') ); + + result = ads_pull_strings(ads, mem_ctx, msg, range_attr, num_values); + + ldap_memfree(first_attr); + if (second_attr != NULL) + ldap_memfree(second_attr); + + return result; +} /** * pull a single uint32 from a ADS result @@ -1960,6 +2042,7 @@ ADS_STATUS ads_workgroup_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char * int i; void *res; const char *attrs[] = {"servicePrincipalName", NULL}; + int num_principals; (*workgroup) = NULL; @@ -1972,7 +2055,8 @@ ADS_STATUS ads_workgroup_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char * return rc; } - principles = ads_pull_strings(ads, mem_ctx, res, "servicePrincipalName"); + principles = ads_pull_strings(ads, mem_ctx, res, + "servicePrincipalName", &num_principals); ads_msgfree(ads, res); -- cgit From 9f662094af4480b45db104a156374e7213aa5d92 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 1 Jan 2004 21:10:35 +0000 Subject: After talking with abartlet remove the fix for bug 707 again. Volker (This used to be commit 0c8ee04c78543b1da3b675df4cf85ee5496c3fbf) --- source3/libads/ldap.c | 100 ++++---------------------------------------------- 1 file changed, 8 insertions(+), 92 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index f47645c7e7..ce0341b72c 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1579,26 +1579,27 @@ char *ads_pull_string(ADS_STRUCT *ads, * @return Result strings in talloc context **/ char **ads_pull_strings(ADS_STRUCT *ads, - TALLOC_CTX *mem_ctx, void *msg, const char *field, - int *num_values) + TALLOC_CTX *mem_ctx, void *msg, const char *field) { char **values; char **ret = NULL; - int i; + int i, n; values = ldap_get_values(ads->ld, msg, field); if (!values) return NULL; - *num_values = ldap_count_values(values); + for (i=0;values[i];i++) + /* noop */ ; + n = i; - ret = talloc(mem_ctx, sizeof(char *) * (*num_values+1)); + ret = talloc(mem_ctx, sizeof(char *) * (n+1)); if (!ret) { ldap_value_free(values); return NULL; } - for (i=0;i<*num_values;i++) { + for (i=0;ild, (LDAPMessage *)msg, &ptr); - - if (first_attr == NULL) - return NULL; - - expected_range_attrib = talloc_asprintf(mem_ctx, "%s;Range=", field); - - if (!strequal(first_attr, field) && - !strnequal(first_attr, expected_range_attrib, - strlen(expected_range_attrib))) - { - DEBUG(1, ("Expected attribute [%s], got [%s]\n", - field, first_attr)); - return NULL; - } - - second_attr = ldap_next_attribute(ads->ld, (LDAPMessage *)msg, ptr); - ber_free(ptr, 0); - - DEBUG(10,("attr: [%s], first_attr: [%s], second_attr: [%s]\n", - field, first_attr, second_attr)); - - if ((second_attr != NULL) && - (strnequal(second_attr, expected_range_attrib, - strlen(expected_range_attrib)))) { - - /* This is the first in a row of range results. We can not ask - * for the attribute we wanted, as this is empty in the LDAP - * msg, the delivered values are in the second range-augmented - * attribute. */ - range_attr = second_attr; - - } else { - - /* Upon second and subsequent requests to get attribute - * values, first_attr carries the Range= specifier. */ - range_attr = first_attr; - - } - - /* We have to ask for more if we have a range specifier in the - * attribute and the attribute does not end in "*". */ - - *more_values = ( (strnequal(range_attr, expected_range_attrib, - strlen(expected_range_attrib))) && - (range_attr[strlen(range_attr)-1] != '*') ); - - result = ads_pull_strings(ads, mem_ctx, msg, range_attr, num_values); - - ldap_memfree(first_attr); - if (second_attr != NULL) - ldap_memfree(second_attr); - - return result; -} /** * pull a single uint32 from a ADS result @@ -2042,7 +1960,6 @@ ADS_STATUS ads_workgroup_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char * int i; void *res; const char *attrs[] = {"servicePrincipalName", NULL}; - int num_principals; (*workgroup) = NULL; @@ -2055,8 +1972,7 @@ ADS_STATUS ads_workgroup_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char * return rc; } - principles = ads_pull_strings(ads, mem_ctx, res, - "servicePrincipalName", &num_principals); + principles = ads_pull_strings(ads, mem_ctx, res, "servicePrincipalName"); ads_msgfree(ads, res); -- cgit From 39c7d3dc4a89f41c9463963366e9b92442a38e30 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 5 Jan 2004 00:13:00 +0000 Subject: Add a utilty function for converting a sid to a DN. Andrew Bartlett (This used to be commit 49a7a3fd17cfeef439e2049a51dbfcbc037f1a93) --- source3/libads/ads_ldap.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ads_ldap.c b/source3/libads/ads_ldap.c index dcceaaeb83..177e8632f6 100644 --- a/source3/libads/ads_ldap.c +++ b/source3/libads/ads_ldap.c @@ -152,4 +152,78 @@ done: return status; } +/* convert a sid to a DN */ + +NTSTATUS ads_sid_to_dn(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + const DOM_SID *sid, + char **dn) +{ + ADS_STATUS rc; + LDAPMessage *msg = NULL; + LDAPMessage *entry = NULL; + char *ldap_exp = NULL; + char *sidstr = NULL; + int count; + char *dn2; + NTSTATUS status = NT_STATUS_UNSUCCESSFUL; + + if (!(sidstr = sid_binstring(sid))) { + DEBUG(1,("ads_sid_to_dn: sid_binstring failed!\n")); + status = NT_STATUS_NO_MEMORY; + goto done; + } + + if (asprintf(&ldap_exp, "(objectSid=%s)", sidstr) == -1) { + DEBUG(1,("ads_sid_to_dn: asprintf failed!\n")); + status = NT_STATUS_NO_MEMORY; + goto done; + } + + rc = ads_search_retry(ads, &msg, ldap_exp, NULL); + if (!ADS_ERR_OK(rc)) { + status = ads_ntstatus(rc); + DEBUG(1,("ads_sid_to_dn ads_search: %s\n", ads_errstr(rc))); + goto done; + } + + if ((count = ads_count_replies(msg)) != 1) { + DEBUG(1,("ads_sid_to_dn (sid=%s): Not found (count=%d)\n", + sid_to_string(sid_string, sid)), count); + status = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + entry = ads_first_entry(msg); + + dn2 = ads_get_dn(ads, entry); + + if (!dn2) { + status = NT_STATUS_NO_MEMORY; + goto done; + } + + *dn = talloc_strdup(mem_ctx, dn2); + + if (!*dn) { + SAFE_FREE(dn2); + status = NT_STATUS_NO_MEMORY; + goto done; + } + + status = NT_STATUS_OK; + + DEBUG(3,("ads sid_to_dn mapped %s\n", *dn2)); + + SAFE_FREE(dn2); +done: + if (msg) ads_msgfree(ads, msg); + + SAFE_FREE(ldap_exp); + SAFE_FREE(sidstr); + + return status; +} + + #endif -- cgit From 11bd06198b3ed4682229956fdec260a1e109ea21 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 5 Jan 2004 01:06:56 +0000 Subject: I'm not quite sure what happened here - but replace the ads_sid_to_dn function with one that compiles. Andrew Bartlett (This used to be commit 0d5b0345a60741ae50f6770d9cecf698864cd209) --- source3/libads/ads_ldap.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_ldap.c b/source3/libads/ads_ldap.c index 177e8632f6..776bdd2359 100644 --- a/source3/libads/ads_ldap.c +++ b/source3/libads/ads_ldap.c @@ -162,7 +162,7 @@ NTSTATUS ads_sid_to_dn(ADS_STRUCT *ads, ADS_STATUS rc; LDAPMessage *msg = NULL; LDAPMessage *entry = NULL; - char *ldap_exp = NULL; + char *ldap_exp; char *sidstr = NULL; int count; char *dn2; @@ -174,27 +174,28 @@ NTSTATUS ads_sid_to_dn(ADS_STRUCT *ads, goto done; } - if (asprintf(&ldap_exp, "(objectSid=%s)", sidstr) == -1) { - DEBUG(1,("ads_sid_to_dn: asprintf failed!\n")); + if(!(ldap_exp = talloc_asprintf(mem_ctx, "(objectSid=%s)", sidstr))) { + DEBUG(1,("ads_sid_to_dn: talloc_asprintf failed!\n")); status = NT_STATUS_NO_MEMORY; goto done; } - rc = ads_search_retry(ads, &msg, ldap_exp, NULL); + rc = ads_search_retry(ads, (void **)&msg, ldap_exp, NULL); if (!ADS_ERR_OK(rc)) { status = ads_ntstatus(rc); DEBUG(1,("ads_sid_to_dn ads_search: %s\n", ads_errstr(rc))); goto done; } - if ((count = ads_count_replies(msg)) != 1) { + if ((count = ads_count_replies(ads, msg)) != 1) { + fstring sid_string; DEBUG(1,("ads_sid_to_dn (sid=%s): Not found (count=%d)\n", - sid_to_string(sid_string, sid)), count); + sid_to_string(sid_string, sid), count)); status = NT_STATUS_UNSUCCESSFUL; goto done; } - entry = ads_first_entry(msg); + entry = ads_first_entry(ads, msg); dn2 = ads_get_dn(ads, entry); @@ -213,13 +214,12 @@ NTSTATUS ads_sid_to_dn(ADS_STRUCT *ads, status = NT_STATUS_OK; - DEBUG(3,("ads sid_to_dn mapped %s\n", *dn2)); + DEBUG(3,("ads sid_to_dn mapped %s\n", dn2)); SAFE_FREE(dn2); done: if (msg) ads_msgfree(ads, msg); - SAFE_FREE(ldap_exp); SAFE_FREE(sidstr); return status; -- cgit From 685e0cbeb846cfbd09bb0f497968c5354f13de00 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 5 Jan 2004 01:48:21 +0000 Subject: Fix for bug 707, getent group for huge ads groups (>1500 members) This introduces range retrieval of ADS attributes. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit VL rewrote most of Günther's patch, partly to remove code duplication and partly to get the retrieval of members in one rush, not interrupted by the lookups for the DN. I rewrote that patch, to ensure that we can keep an eye on the USN (sequence number) of the entry - this allows us to ensure the read was atomic. In particular, the range retrieval is now generic, for strings. It could easily be made generic for any attribute type, if need be. Andrew Bartlett (This used to be commit 131bb928f19c7b1f582c4ad9ac42e5f3d9dfb622) --- source3/libads/ldap.c | 138 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 130 insertions(+), 8 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index ce0341b72c..f9c7820275 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1579,27 +1579,26 @@ char *ads_pull_string(ADS_STRUCT *ads, * @return Result strings in talloc context **/ char **ads_pull_strings(ADS_STRUCT *ads, - TALLOC_CTX *mem_ctx, void *msg, const char *field) + TALLOC_CTX *mem_ctx, void *msg, const char *field, + size_t *num_values) { char **values; char **ret = NULL; - int i, n; + int i; values = ldap_get_values(ads->ld, msg, field); if (!values) return NULL; - for (i=0;values[i];i++) - /* noop */ ; - n = i; + *num_values = ldap_count_values(values); - ret = talloc(mem_ctx, sizeof(char *) * (n+1)); + ret = talloc(mem_ctx, sizeof(char *) * (*num_values+1)); if (!ret) { ldap_value_free(values); return NULL; } - for (i=0;i Date: Mon, 5 Jan 2004 02:04:37 +0000 Subject: rpc_client/cli_lsarpc.c: rpc_parse/parse_lsa.c: nsswitch/winbindd_rpc.c: nsswitch/winbindd.h: - Add const libads/ads_ldap.c: - Cleanup function for use nsswitch/winbindd_ads.c: - Use new utility function ads_sid_to_dn - Don't search for 'dn=', rather call the ads_search_retry_dn() nsswitch/winbindd_ads.c: include/rpc_ds.h: rpc_client/cli_ds.c: - Fixup braindamage in cli_ds_enum_domain_trusts(): - This function was returning a UNISTR2 up to the caller, and was doing nasty (invalid, per valgrind) things with memcpy() - Create a new structure that represents this informaiton in a useful way and use talloc. Andrew Bartlett (This used to be commit 06c3f15aa166bb567d8be0a8bc4b095b167ab371) --- source3/libads/ads_ldap.c | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_ldap.c b/source3/libads/ads_ldap.c index 776bdd2359..944cb1599c 100644 --- a/source3/libads/ads_ldap.c +++ b/source3/libads/ads_ldap.c @@ -152,12 +152,13 @@ done: return status; } + /* convert a sid to a DN */ -NTSTATUS ads_sid_to_dn(ADS_STRUCT *ads, - TALLOC_CTX *mem_ctx, - const DOM_SID *sid, - char **dn) +ADS_STATUS ads_sid_to_dn(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + const DOM_SID *sid, + char **dn) { ADS_STATUS rc; LDAPMessage *msg = NULL; @@ -165,24 +166,28 @@ NTSTATUS ads_sid_to_dn(ADS_STRUCT *ads, char *ldap_exp; char *sidstr = NULL; int count; - char *dn2; - NTSTATUS status = NT_STATUS_UNSUCCESSFUL; + char *dn2 = NULL; + + const char *attr[] = { + "dn", + NULL + }; if (!(sidstr = sid_binstring(sid))) { DEBUG(1,("ads_sid_to_dn: sid_binstring failed!\n")); - status = NT_STATUS_NO_MEMORY; + rc = ADS_ERROR_NT(NT_STATUS_NO_MEMORY); goto done; } if(!(ldap_exp = talloc_asprintf(mem_ctx, "(objectSid=%s)", sidstr))) { DEBUG(1,("ads_sid_to_dn: talloc_asprintf failed!\n")); - status = NT_STATUS_NO_MEMORY; + rc = ADS_ERROR_NT(NT_STATUS_NO_MEMORY); goto done; } - rc = ads_search_retry(ads, (void **)&msg, ldap_exp, NULL); + rc = ads_search_retry(ads, (void **)&msg, ldap_exp, attr); + if (!ADS_ERR_OK(rc)) { - status = ads_ntstatus(rc); DEBUG(1,("ads_sid_to_dn ads_search: %s\n", ads_errstr(rc))); goto done; } @@ -191,7 +196,7 @@ NTSTATUS ads_sid_to_dn(ADS_STRUCT *ads, fstring sid_string; DEBUG(1,("ads_sid_to_dn (sid=%s): Not found (count=%d)\n", sid_to_string(sid_string, sid), count)); - status = NT_STATUS_UNSUCCESSFUL; + rc = ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL); goto done; } @@ -200,30 +205,30 @@ NTSTATUS ads_sid_to_dn(ADS_STRUCT *ads, dn2 = ads_get_dn(ads, entry); if (!dn2) { - status = NT_STATUS_NO_MEMORY; + rc = ADS_ERROR_NT(NT_STATUS_NO_MEMORY); goto done; } *dn = talloc_strdup(mem_ctx, dn2); if (!*dn) { - SAFE_FREE(dn2); - status = NT_STATUS_NO_MEMORY; + ads_memfree(ads, dn2); + rc = ADS_ERROR_NT(NT_STATUS_NO_MEMORY); goto done; } - status = NT_STATUS_OK; + rc = ADS_ERROR_NT(NT_STATUS_OK); DEBUG(3,("ads sid_to_dn mapped %s\n", dn2)); SAFE_FREE(dn2); done: if (msg) ads_msgfree(ads, msg); + if (dn2) ads_memfree(ads, dn2); SAFE_FREE(sidstr); - return status; + return rc; } - #endif -- cgit From 3c2371dcfc83ef7b9605e7450cdf8945723a3d1e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 5 Jan 2004 02:12:38 +0000 Subject: There is some memory corruption hidden somewhere in our winbind code. If I could reproduce it, I would fix it, but for now just make sure we always SAFE_FREE() and set our starting pointers to NULL. Andrew Bartlett (This used to be commit c279e178bc122e1e2aa519f7a373a3d93672a3ac) --- source3/libads/ldap_utils.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap_utils.c b/source3/libads/ldap_utils.c index 4142bceabc..991f16c845 100644 --- a/source3/libads/ldap_utils.c +++ b/source3/libads/ldap_utils.c @@ -35,6 +35,8 @@ ADS_STATUS ads_do_search_retry(ADS_STRUCT *ads, const char *bind_path, int scope int count = 3; char *bp; + *res = NULL; + if (!ads->ld && time(NULL) - ads->last_attempt < ADS_RECONNECT_TIME) { return ADS_ERROR(LDAP_SERVER_DOWN); @@ -42,15 +44,17 @@ ADS_STATUS ads_do_search_retry(ADS_STRUCT *ads, const char *bind_path, int scope bp = strdup(bind_path); - if (!bp) + if (!bp) { return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + } while (count--) { + *res = NULL; status = ads_do_search_all(ads, bp, scope, expr, attrs, res); if (ADS_ERR_OK(status)) { DEBUG(5,("Search for %s gave %d replies\n", expr, ads_count_replies(ads, *res))); - free(bp); + SAFE_FREE(bp); return status; } @@ -72,11 +76,11 @@ ADS_STATUS ads_do_search_retry(ADS_STRUCT *ads, const char *bind_path, int scope DEBUG(1,("ads_search_retry: failed to reconnect (%s)\n", ads_errstr(status))); ads_destroy(&ads); - free(bp); + SAFE_FREE(bp); return status; } } - free(bp); + SAFE_FREE(bp); if (!ADS_ERR_OK(status)) DEBUG(1,("ads reopen failed after error %s\n", -- cgit From e4f8914c3f8ef1028c95468295be862dbbb03a05 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 5 Jan 2004 12:20:15 +0000 Subject: Try to keep vl happy - shorten some of these lines. (This used to be commit 3a4c56e4c60854bbd291adc7d321d3869e6dedab) --- source3/libads/ldap.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index f9c7820275..8039d3d1d4 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1674,7 +1674,8 @@ char **ads_pull_strings_range(ADS_STRUCT *ads, &range_start) == 1) { *more_strings = False; } else { - DEBUG(1, ("ads_pull_strings_range: Cannot parse Range attriubte (%s)\n", range_attr)); + DEBUG(1, ("ads_pull_strings_range: Cannot parse Range attriubte (%s)\n", + range_attr)); ldap_memfree(range_attr); *more_strings = False; return NULL; @@ -1682,7 +1683,8 @@ char **ads_pull_strings_range(ADS_STRUCT *ads, } if ((*num_strings) != range_start) { - DEBUG(1, ("ads_pull_strings_range: Range attribute (%s) doesn't start at %u, but at %lu - aborting range retreival\n", + DEBUG(1, ("ads_pull_strings_range: Range attribute (%s) doesn't start at %u, but at %lu" + " - aborting range retreival\n", range_attr, *num_strings + 1, range_start)); ldap_memfree(range_attr); *more_strings = False; @@ -1692,8 +1694,10 @@ char **ads_pull_strings_range(ADS_STRUCT *ads, new_strings = ads_pull_strings(ads, mem_ctx, msg, range_attr, &num_new_strings); if (*more_strings && ((*num_strings + num_new_strings) != (range_end + 1))) { - DEBUG(1, ("ads_pull_strings_range: Range attribute (%s) tells us we have %lu strings in this bunch, but we only got %lu - aborting range retreival\n", - range_attr, (unsigned long int)range_end - range_start + 1, (unsigned long int)num_new_strings)); + DEBUG(1, ("ads_pull_strings_range: Range attribute (%s) tells us we have %lu " + "strings in this bunch, but we only got %lu - aborting range retreival\n", + range_attr, (unsigned long int)range_end - range_start + 1, + (unsigned long int)num_new_strings)); ldap_memfree(range_attr); *more_strings = False; return NULL; @@ -1996,7 +2000,8 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads) p = strchr(value, ':'); if (!p) { talloc_destroy(ctx); - DEBUG(1, ("ads_server_info: returned ldap server name did not contain a ':' so was deemed invalid\n")); + DEBUG(1, ("ads_server_info: returned ldap server name did not contain a ':' " + "so was deemed invalid\n")); return ADS_ERROR(LDAP_DECODING_ERROR); } @@ -2006,7 +2011,8 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads) p = strchr(ads->config.ldap_server_name, '$'); if (!p || p[1] != '@') { talloc_destroy(ctx); - DEBUG(1, ("ads_server_info: returned ldap server name (%s) does not contain '$@' so was deemed invalid\n", ads->config.ldap_server_name)); + DEBUG(1, ("ads_server_info: returned ldap server name (%s) does not contain '$@'" + " so was deemed invalid\n", ads->config.ldap_server_name)); SAFE_FREE(ads->config.ldap_server_name); return ADS_ERROR(LDAP_DECODING_ERROR); } -- cgit From 333b356b92d2a53b1cc12845c97dd0d8fa44559a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 6 Jan 2004 23:57:12 +0000 Subject: Fix segfualt caused by incorrect configuration. If lp_realm() was not set, but security=ADS, we would attempt to free the principal name that krb5 never allocated. Also fix the dump_data() of the session key, now that we use a data_blob to store that. Andrew Bartlett (This used to be commit 4ad67f13404ef0118265ad66d8bdfa256c914ad0) --- source3/libads/kerberos_verify.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index b0efb8f598..50e6971815 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -173,8 +173,11 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, krb5_rcache rcache = NULL; int ret, i; krb5_keyblock *key = NULL; + krb5_principal host_princ; char *host_princ_s = NULL; + BOOL free_host_princ = False; + fstring myname; char *password_s = NULL; krb5_data password; @@ -239,6 +242,8 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, goto out; } + free_host_princ = True; + /* * JRA. We must set the rcache here. This will prevent replay attacks. */ @@ -339,10 +344,7 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, free(packet.data); get_krb5_smb_session_key(context, auth_context, session_key, True); -#ifdef DEBUG_PASSWORD - DEBUG(10,("SMB session key (from ticket) follows:\n")); - dump_data(10, session_key, 16); -#endif + dump_data_pw("SMB session key (from ticket)\n", session_key->data, session_key->length); #if 0 file_save("/tmp/ticket.dat", ticket->data, ticket->length); @@ -386,7 +388,9 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, if (!NT_STATUS_IS_OK(sret)) data_blob_free(ap_rep); - krb5_free_principal(context, host_princ); + if (free_host_princ) + krb5_free_principal(context, host_princ); + if (tkt != NULL) krb5_free_ticket(context, tkt); free_kerberos_etypes(context, enctypes); -- cgit From 7d068355aae99060acac03c6633509545aa782a4 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 8 Jan 2004 08:19:18 +0000 Subject: This merges in my 'always use ADS' patch. Tested on a mix of NT and ADS domains, this patch ensures that we always use the ADS backend when security=ADS, and the remote server is capable. The routines used for this behaviour have been upgraded to modern Samba codeing standards. This is a change in behaviour for mixed mode domains, and if the trusted domain cannot be reached with our current krb5.conf file, we will show that domain as disconnected. This is in line with existing behaviour for native mode domains, and for our primary domain. As a consequence of testing this patch, I found that our kerberos error handling was well below par - we would often throw away useful error values. These changes move more routines to ADS_STATUS to return kerberos errors. Also found when valgrinding the setup, fix a few memory leaks. While sniffing the resultant connections, I noticed we would query our list of trusted domains twice - so I have reworked some of the code to avoid that. Andrew Bartlett (This used to be commit 7c34de8096b86d2869e7177420fe129bd0c7541d) --- source3/libads/ads_status.c | 11 ++++++++++- source3/libads/sasl.c | 17 ++++++++++++----- 2 files changed, 22 insertions(+), 6 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_status.c b/source3/libads/ads_status.c index 11f9d66b92..63757af860 100644 --- a/source3/libads/ads_status.c +++ b/source3/libads/ads_status.c @@ -77,6 +77,15 @@ NTSTATUS ads_ntstatus(ADS_STATUS status) && (status.err.rc == LDAP_NO_MEMORY)) { return NT_STATUS_NO_MEMORY; } +#endif +#ifdef HAVE_KRB5 + if (status.error_type = ADS_ERROR_KRB5) { + if (status.err.rc == KRB5KDC_ERR_PREAUTH_FAILED) { + return NT_STATUS_LOGON_FAILURE; + } else if (status.err.rc == KRB5_KDC_UNREACH) { + return NT_STATUS_NO_LOGON_SERVERS; + } + } #endif if (ADS_ERR_OK(status)) return NT_STATUS_OK; return NT_STATUS_UNSUCCESSFUL; @@ -123,7 +132,7 @@ const char *ads_errstr(ADS_STATUS status) } #endif case ADS_ERROR_NT: - return nt_errstr(ads_ntstatus(status)); + return get_friendly_nt_error_msg(ads_ntstatus(status)); default: return "Unknown ADS error type!? (not compiled in?)"; } diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 5122803597..1ab71c6ee5 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -124,13 +124,13 @@ static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *princip { DATA_BLOB blob; struct berval cred, *scred; - unsigned char sk[16]; + DATA_BLOB session_key; int rc; - blob = spnego_gen_negTokenTarg(principal, ads->auth.time_offset, sk); + rc = spnego_gen_negTokenTarg(principal, ads->auth.time_offset, &blob, &session_key); - if (!blob.data) { - return ADS_ERROR(LDAP_OPERATIONS_ERROR); + if (rc) { + return ADS_ERROR_KRB5(rc); } /* now send the auth packet and we should be done */ @@ -140,6 +140,7 @@ static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *princip rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred); data_blob_free(&blob); + data_blob_free(&session_key); return ADS_ERROR(rc); } @@ -166,6 +167,8 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) blob = data_blob(scred->bv_val, scred->bv_len); + ber_bvfree(scred); + #if 0 file_save("sasl_spnego.dat", blob.data, blob.length); #endif @@ -196,9 +199,13 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) status = ads_sasl_spnego_krb5_bind(ads, principal); if (ADS_ERR_OK(status)) return status; - if (ads_kinit_password(ads) == 0) { + + status = ADS_ERROR_KRB5(ads_kinit_password(ads)); + + if (ADS_ERR_OK(status)) { status = ads_sasl_spnego_krb5_bind(ads, principal); } + /* only fallback to NTLMSSP if allowed */ if (ADS_ERR_OK(status) || !(ads->auth.flags & ADS_AUTH_ALLOW_NTLMSSP)) { -- cgit From 500c28974ded4c4789d9f197de5860b20447e606 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 9 Jan 2004 14:54:33 +0000 Subject: fix some warnings from the Sun compiler (This used to be commit ebabf72a78f0165521268b73e0fcabe1ea7834fd) --- source3/libads/ads_status.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_status.c b/source3/libads/ads_status.c index 63757af860..463f647f9c 100644 --- a/source3/libads/ads_status.c +++ b/source3/libads/ads_status.c @@ -31,10 +31,10 @@ ADS_STATUS ads_build_error(enum ads_error_type etype, { ADS_STATUS ret; - if (etype == ADS_ERROR_NT) { - DEBUG(0,("don't use ads_build_error with ADS_ERROR_NT!\n")); + if (etype == ENUM_ADS_ERROR_NT) { + DEBUG(0,("don't use ads_build_error with ENUM_ADS_ERROR_NT!\n")); ret.err.rc = -1; - ret.error_type = ADS_ERROR_SYSTEM; + ret.error_type = ENUM_ADS_ERROR_SYSTEM; ret.minor_status = 0; return ret; } @@ -50,10 +50,10 @@ ADS_STATUS ads_build_nt_error(enum ads_error_type etype, { ADS_STATUS ret; - if (etype != ADS_ERROR_NT) { - DEBUG(0,("don't use ads_build_nt_error without ADS_ERROR_NT!\n")); + if (etype != ENUM_ADS_ERROR_NT) { + DEBUG(0,("don't use ads_build_nt_error without ENUM_ADS_ERROR_NT!\n")); ret.err.rc = -1; - ret.error_type = ADS_ERROR_SYSTEM; + ret.error_type = ENUM_ADS_ERROR_SYSTEM; ret.minor_status = 0; return ret; } @@ -69,17 +69,17 @@ ADS_STATUS ads_build_nt_error(enum ads_error_type etype, */ NTSTATUS ads_ntstatus(ADS_STATUS status) { - if (status.error_type == ADS_ERROR_NT){ + if (status.error_type == ENUM_ADS_ERROR_NT){ return status.err.nt_status; } #ifdef HAVE_LDAP - if ((status.error_type == ADS_ERROR_LDAP) + if ((status.error_type == ENUM_ADS_ERROR_LDAP) && (status.err.rc == LDAP_NO_MEMORY)) { return NT_STATUS_NO_MEMORY; } #endif #ifdef HAVE_KRB5 - if (status.error_type = ADS_ERROR_KRB5) { + if (status.error_type == ENUM_ADS_ERROR_KRB5) { if (status.err.rc == KRB5KDC_ERR_PREAUTH_FAILED) { return NT_STATUS_LOGON_FAILURE; } else if (status.err.rc == KRB5_KDC_UNREACH) { @@ -103,18 +103,18 @@ const char *ads_errstr(ADS_STATUS status) msg_ctx = 0; switch (status.error_type) { - case ADS_ERROR_SYSTEM: + case ENUM_ADS_ERROR_SYSTEM: return strerror(status.err.rc); #ifdef HAVE_LDAP - case ADS_ERROR_LDAP: + case ENUM_ADS_ERROR_LDAP: return ldap_err2string(status.err.rc); #endif #ifdef HAVE_KRB5 - case ADS_ERROR_KRB5: + case ENUM_ADS_ERROR_KRB5: return error_message(status.err.rc); #endif #ifdef HAVE_GSSAPI - case ADS_ERROR_GSS: + case ENUM_ADS_ERROR_GSS: { uint32 minor; @@ -131,7 +131,7 @@ const char *ads_errstr(ADS_STATUS status) return ret; } #endif - case ADS_ERROR_NT: + case ENUM_ADS_ERROR_NT: return get_friendly_nt_error_msg(ads_ntstatus(status)); default: return "Unknown ADS error type!? (not compiled in?)"; -- cgit From 160d3e2a9c5480f88a482d34fac151bc400b1fd0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 3 Feb 2004 03:23:18 +0000 Subject: Fix for a bug where the mutex could be left locked. Also remove the memory keytab code which has no effect. Driven by bug report from "Rob J. Caskey" . Jeremy. (This used to be commit 4cb8facbf9fa6fa5233fdb363ceac4b304d263d4) --- source3/libads/kerberos_verify.c | 154 ++------------------------------------- 1 file changed, 8 insertions(+), 146 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 50e6971815..47559c1abb 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -26,135 +26,6 @@ #ifdef HAVE_KRB5 -static void free_keytab(krb5_context context, krb5_keytab keytab) -{ - int ret=0; - - if (keytab) - ret = krb5_kt_close(context, keytab); - if (ret) { - DEBUG(3, ("krb5_kt_close failed (%s)\n", - error_message(ret))); - } -} - -#ifdef HAVE_MEMORY_KEYTAB -static krb5_error_code create_keytab(krb5_context context, - krb5_principal host_princ, - char *host_princ_s, - krb5_data password, - krb5_enctype *enctypes, - krb5_keytab *keytab, - char *keytab_name) -{ - krb5_keytab_entry entry; - krb5_kvno kvno = 1; - krb5_error_code ret; - krb5_keyblock *key; - int i; - - DEBUG(10,("creating keytab: %s\n", keytab_name)); - ret = krb5_kt_resolve(context, keytab_name, keytab); - if (ret) - return ret; - - if (!(key = (krb5_keyblock *)malloc(sizeof(*key)))) { - return ENOMEM; - } - - /* add keytab entries for all encryption types */ - for ( i=0; enctypes[i]; i++ ) { - - if (create_kerberos_key_from_string(context, host_princ, &password, key, enctypes[i])) { - continue; - } - - entry.principal = host_princ; - entry.vno = kvno; - -#if !defined(HAVE_KRB5_KEYTAB_ENTRY_KEY) && !defined(HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK) -#error krb5_keytab_entry has no key or keyblock member -#endif - -#ifdef HAVE_KRB5_KEYTAB_ENTRY_KEY /* MIT */ - entry.key = *key; -#endif - -#ifdef HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK /* Heimdal */ - entry.keyblock = *key; -#endif - - DEBUG(10,("adding keytab-entry for (%s) with encryption type (%d)\n", - host_princ_s, enctypes[i])); - ret = krb5_kt_add_entry(context, *keytab, &entry); - if (ret) { - DEBUG(1,("adding entry to keytab failed (%s)\n", - error_message(ret))); - free_keytab(context, *keytab); - return ret; - } - } - krb5_free_keyblock(context, key); - - return 0; -} -#endif - -static BOOL setup_keytab(krb5_context context, - krb5_principal host_princ, - char *host_princ_s, - krb5_data password, - krb5_enctype *enctypes, - krb5_keytab *keytab) -{ - char *keytab_name = NULL; - krb5_error_code ret; - - /* check if we have to setup a keytab - not currently enabled - I've put this in so that the else block below functions - the same way that it will when this code is turned on */ - if (0 /* will later be *lp_keytab() */) { - - /* use a file-keytab */ - asprintf(&keytab_name, "%s:%s", - "" - /* KRB5_KT_FILE_PREFIX, "FILE" or - "WRFILE" depending on HEeimdal or MIT */, - "" /* will later be lp_keytab() */); - - DEBUG(10,("will use filebased keytab: %s\n", keytab_name)); - ret = krb5_kt_resolve(context, keytab_name, keytab); - if (ret) { - DEBUG(3,("cannot resolve keytab name %s (%s)\n", - keytab_name, - error_message(ret))); - SAFE_FREE(keytab_name); - return False; - } - - } - -#if defined(HAVE_MEMORY_KEYTAB) - else { - - /* setup a in-memory-keytab */ - asprintf(&keytab_name, "MEMORY:"); - - ret = create_keytab(context, host_princ, host_princ_s, password, enctypes, - keytab, keytab_name); - if (ret) { - DEBUG(3,("unable to create MEMORY: keytab (%s)\n", - error_message(ret))); - SAFE_FREE(keytab_name); - return False; - } - } -#endif - SAFE_FREE(keytab_name); - return True; -} - - /* verify an incoming ticket and parse out the principal name and authorization_data if available @@ -167,7 +38,6 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, NTSTATUS sret = NT_STATUS_LOGON_FAILURE; krb5_context context = NULL; krb5_auth_context auth_context = NULL; - krb5_keytab keytab = NULL; krb5_data packet; krb5_ticket *tkt = NULL; krb5_rcache rcache = NULL; @@ -177,6 +47,7 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, krb5_principal host_princ; char *host_princ_s = NULL; BOOL free_host_princ = False; + BOOL got_replay_mutex = False; fstring myname; char *password_s = NULL; @@ -280,13 +151,8 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, goto out; } - if (!setup_keytab(context, host_princ, host_princ_s, password, - enctypes, &keytab)) { - DEBUG(3,("ads_verify_ticket: unable to setup keytab\n")); - sret = NT_STATUS_LOGON_FAILURE; - goto out; - } - + got_replay_mutex = True; + /* We need to setup a auth context with each possible encoding type in turn. */ for (i=0;enctypes[i];i++) { if (!(key = (krb5_keyblock *)malloc(sizeof(*key)))) { @@ -306,12 +172,8 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, packet.data = (krb5_pointer)ticket->data; if (!(ret = krb5_rd_req(context, &auth_context, &packet, -#ifdef HAVE_MEMORY_KEYTAB - host_princ, -#else NULL, -#endif - keytab, NULL, &tkt))) { + NULL, NULL, &tkt))) { DEBUG(10,("ads_verify_ticket: enc type [%u] decrypted message !\n", (unsigned int)enctypes[i] )); auth_ok = True; @@ -324,6 +186,7 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, } release_server_mutex(); + got_replay_mutex = False; if (!auth_ok) { DEBUG(3,("ads_verify_ticket: krb5_rd_req with auth failed (%s)\n", @@ -366,10 +229,6 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, } #endif - - /* get rid of all resources associated with the keytab */ - if (keytab) free_keytab(context, keytab); - if ((ret = krb5_unparse_name(context, get_principal_from_tkt(tkt), principal))) { DEBUG(3,("ads_verify_ticket: krb5_unparse_name failed (%s)\n", @@ -382,6 +241,9 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, out: + if (got_replay_mutex) + release_server_mutex(); + if (!NT_STATUS_IS_OK(sret)) data_blob_free(auth_data); -- cgit From d57d2d08978e37ab771479b5f2f2f7f36d867b69 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 8 Feb 2004 00:31:36 +0000 Subject: Bug found by gd - the new range-reterival code did still had 'member' hardcoded into it. This didn't matter, as we only use it for 'member' so far... Andrew Bartlett (This used to be commit 8621899112e720411715ea53558d5146ff04eeb0) --- source3/libads/ldap.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 8039d3d1d4..15504a5202 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1661,7 +1661,7 @@ char **ads_pull_strings_range(ADS_STRUCT *ads, } if (!attr) { ber_free(ptr, 0); - /* nothing here - this feild is just empty */ + /* nothing here - this field is just empty */ *more_strings = False; return NULL; } @@ -1720,7 +1720,8 @@ char **ads_pull_strings_range(ADS_STRUCT *ads, if (*more_strings) { *next_attribute = talloc_asprintf(mem_ctx, - "member;range=%d-*", + "%s;range=%d-*", + field, *num_strings); if (!*next_attribute) { -- cgit From 14dd75d181293fa5335184d2d836834a42edcbb4 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 22 Mar 2004 22:49:40 +0000 Subject: bug 1195: add flag to ADS_STRUCT so we know who owns the main structure's memory (not the members though) (This used to be commit 4449e0e251190b741f51348819669453f0758f36) --- source3/libads/ads_struct.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index 9774968e12..92f37093f4 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -102,13 +102,10 @@ ADS_STRUCT *ads_init(const char *realm, ads->server.foreign = 1; } - return ads; -} + /* the caller will own the memory by default */ + ads->is_mine = 1; -/* a simpler ads_init() interface using all defaults */ -ADS_STRUCT *ads_init_simple(void) -{ - return ads_init(NULL, NULL, NULL); + return ads; } /* @@ -117,6 +114,9 @@ ADS_STRUCT *ads_init_simple(void) void ads_destroy(ADS_STRUCT **ads) { if (ads && *ads) { + BOOL is_mine; + + is_mine = (*ads)->is_mine; #if HAVE_LDAP if ((*ads)->ld) ldap_unbind((*ads)->ld); #endif @@ -133,8 +133,11 @@ void ads_destroy(ADS_STRUCT **ads) SAFE_FREE((*ads)->config.realm); SAFE_FREE((*ads)->config.bind_path); SAFE_FREE((*ads)->config.ldap_server_name); - + + ZERO_STRUCTP(*ads); - SAFE_FREE(*ads); + + if ( is_mine ) + SAFE_FREE(*ads); } } -- cgit From 9a8e30d04b1cfc53e8c8949a56d4f1cf5aa26501 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Wed, 24 Mar 2004 17:32:55 +0000 Subject: Fix bugzilla # 1208 Winbind tickets expired. We now check the expiration time, and acquire new tickets. We couln't rely on renewing them, because if we didn't get a request before they expired, we wouldn't have renewed them. Also, there is a one-week limit in MS on renewal life, so new tickets would have been needed after a week anyway. Default is 10 hours, so we should only be acquiring them that often, unless the configuration on the DC is changed (and the minimum is 1 hour). (This used to be commit c2436c433afaab4006554a86307f76b6689d6929) --- source3/libads/kerberos.c | 39 +++++++++++++++++++++++++++++++++++++-- source3/libads/krb5_setpw.c | 2 +- 2 files changed, 38 insertions(+), 3 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index bef2febaef..70f6f3386c 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -54,7 +54,7 @@ kerb_prompter(krb5_context ctx, void *data, simulate a kinit, putting the tgt in the default cache location remus@snapserver.com */ -int kerberos_kinit_password(const char *principal, const char *password, int time_offset) +int kerberos_kinit_password(const char *principal, const char *password, int time_offset, time_t *expire_time) { krb5_context ctx; krb5_error_code code = 0; @@ -102,6 +102,9 @@ int kerberos_kinit_password(const char *principal, const char *password, int tim return code; } + if (expire_time) + *expire_time = (time_t) my_creds.times.endtime; + krb5_cc_close(ctx, cc); krb5_free_cred_contents(ctx, &my_creds); krb5_free_principal(ctx, me); @@ -126,7 +129,7 @@ int ads_kinit_password(ADS_STRUCT *ads) return KRB5_LIBOS_CANTREADPWD; } - ret = kerberos_kinit_password(s, ads->auth.password, ads->auth.time_offset); + ret = kerberos_kinit_password(s, ads->auth.password, ads->auth.time_offset, &ads->auth.expire); if (ret) { DEBUG(0,("kerberos_kinit_password %s failed: %s\n", @@ -136,5 +139,37 @@ int ads_kinit_password(ADS_STRUCT *ads) return ret; } +int ads_kdestroy(const char *cc_name) +{ + krb5_error_code code; + krb5_context ctx; + krb5_ccache cc; + + if ((code = krb5_init_context (&ctx))) { + DEBUG(3, ("ads_kdestroy: kdb5_init_context rc=%d\n", code)); + return code; + } + + if (!cc_name) { + if ((code = krb5_cc_default(ctx, &cc))) { + krb5_free_context(ctx); + return code; + } + } else { + if ((code = krb5_cc_resolve(ctx, cc_name, &cc))) { + DEBUG(3, ("ads_kdestroy: krb5_cc_resolve rc=%d\n", + code)); + krb5_free_context(ctx); + return code; + } + } + + if ((code = krb5_cc_destroy (ctx, cc))) { + DEBUG(3, ("ads_kdestroy: krb5_cc_destroy rc=%d\n", code)); + } + + krb5_free_context (ctx); + return code; +} #endif diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 9cf15221a8..16d3df83e9 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -642,7 +642,7 @@ ADS_STATUS kerberos_set_password(const char *kpasswd_server, { int ret; - if ((ret = kerberos_kinit_password(auth_principal, auth_password, time_offset))) { + if ((ret = kerberos_kinit_password(auth_principal, auth_password, time_offset, NULL))) { DEBUG(1,("Failed kinit for principal %s (%s)\n", auth_principal, error_message(ret))); return ADS_ERROR_KRB5(ret); } -- cgit From 931df5850e326ad0639fe317e0ca82e6d820a68e Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 5 Apr 2004 12:19:50 +0000 Subject: r39: * importing .cvsignore files * updateing WHATSNEW with vl's change (This used to be commit a7e2730ec4389e0c249886a8bfe1ee14c5abac41) --- source3/libads/.cvsignore | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 source3/libads/.cvsignore (limited to 'source3/libads') diff --git a/source3/libads/.cvsignore b/source3/libads/.cvsignore deleted file mode 100644 index 5f2a5c4cf7..0000000000 --- a/source3/libads/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -*.po -*.po32 -- cgit From 8ad3d8c9b065f3a2040beff801bdc9dceac868a8 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 13 Apr 2004 14:39:48 +0000 Subject: r196: merging struct uuid from trunk (This used to be commit 911a28361b9d8dd50597627f245ebfb57c6294fb) --- source3/libads/ldap.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 15504a5202..20a36dfdf5 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1106,20 +1106,14 @@ static void dump_binary(const char *field, struct berval **values) } } -struct uuid { - uint32 i1; - uint16 i2; - uint16 i3; - uint8 s[8]; -}; - static void dump_guid(const char *field, struct berval **values) { int i; - GUID guid; + UUID_FLAT guid; for (i=0; values[i]; i++) { memcpy(guid.info, values[i]->bv_val, sizeof(guid.info)); - printf("%s: %s\n", field, smb_uuid_string_static(guid)); + printf("%s: %s\n", field, + smb_uuid_string_static(smb_uuid_unpack_static(guid))); } } @@ -1771,16 +1765,18 @@ BOOL ads_pull_uint32(ADS_STRUCT *ads, * @return boolean indicating success **/ BOOL ads_pull_guid(ADS_STRUCT *ads, - void *msg, GUID *guid) + void *msg, struct uuid *guid) { char **values; + UUID_FLAT flat_guid; values = ldap_get_values(ads->ld, msg, "objectGUID"); if (!values) return False; if (values[0]) { - memcpy(guid, values[0], sizeof(GUID)); + memcpy(&flat_guid.info, values[0], sizeof(UUID_FLAT)); + smb_uuid_unpack(flat_guid, guid); ldap_value_free(values); return True; } -- cgit From 13aa693f35336db17df1d7cb55ab86efbcc230ee Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 6 May 2004 23:08:56 +0000 Subject: r533: More memory leak fixes from kawasa_r@itg.hitachi.co.jp. I need to valgrind winbindd with these in.... Jeremy. (This used to be commit fa4774b73d338a0c0df09f23cd738279bf4e71a2) --- source3/libads/sasl.c | 40 ++++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 1ab71c6ee5..971156ae61 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -29,12 +29,12 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) { const char *mechs[] = {OID_NTLMSSP, NULL}; - DATA_BLOB msg1; + DATA_BLOB msg1 = data_blob(NULL, 0); DATA_BLOB blob, chal1, chal2, auth; uint8 challenge[8]; uint8 nthash[24], lmhash[24], sess_key[16]; uint32 neg_flags; - struct berval cred, *scred; + struct berval cred, *scred = NULL; ADS_STATUS status; int rc; @@ -70,6 +70,7 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) } blob = data_blob(scred->bv_val, scred->bv_len); + ber_bvfree(scred); /* the server gives us back two challenges */ if (!spnego_parse_challenge(blob, &chal1, &chal2)) { @@ -105,15 +106,29 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) data_blob_free(&blob); + /* Remember to free the msg1 blob. The contents of this + have been copied into cred and need freeing before reassignment. */ + data_blob_free(&msg1); + /* now send the auth packet and we should be done */ cred.bv_val = (char *)auth.data; cred.bv_len = auth.length; rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred); + ber_bvfree(scred); + data_blob_free(&auth); + return ADS_ERROR(rc); failed: + + /* Remember to free the msg1 blob. The contents of this + have been copied into cred and need freeing. */ + data_blob_free(&msg1); + + if(scred) + ber_bvfree(scred); return status; } @@ -122,9 +137,9 @@ failed: */ static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *principal) { - DATA_BLOB blob; - struct berval cred, *scred; - DATA_BLOB session_key; + DATA_BLOB blob = data_blob(NULL, 0); + struct berval cred, *scred = NULL; + DATA_BLOB session_key = data_blob(NULL, 0); int rc; rc = spnego_gen_negTokenTarg(principal, ads->auth.time_offset, &blob, &session_key); @@ -141,6 +156,8 @@ static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *princip data_blob_free(&blob); data_blob_free(&session_key); + if(scred) + ber_bvfree(scred); return ADS_ERROR(rc); } @@ -154,7 +171,7 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) int rc, i; ADS_STATUS status; DATA_BLOB blob; - char *principal; + char *principal = NULL; char *OIDs[ASN1_MAX_OIDS]; BOOL got_kerberos_mechanism = False; @@ -197,8 +214,10 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) if (!(ads->auth.flags & ADS_AUTH_DISABLE_KERBEROS) && got_kerberos_mechanism) { status = ads_sasl_spnego_krb5_bind(ads, principal); - if (ADS_ERR_OK(status)) + if (ADS_ERR_OK(status)) { + SAFE_FREE(principal); return status; + } status = ADS_ERROR_KRB5(ads_kinit_password(ads)); @@ -209,11 +228,14 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) /* only fallback to NTLMSSP if allowed */ if (ADS_ERR_OK(status) || !(ads->auth.flags & ADS_AUTH_ALLOW_NTLMSSP)) { + SAFE_FREE(principal); return status; } } #endif + SAFE_FREE(principal); + /* lets do NTLMSSP ... this has the big advantage that we don't need to sync clocks, and we don't rely on special versions of the krb5 library for HMAC_MD4 encryption */ @@ -242,7 +264,7 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) gss_buffer_desc output_token, input_token; uint32 ret_flags, conf_state; struct berval cred; - struct berval *scred; + struct berval *scred = NULL; int i=0; int gss_rc, rc; uint8 *p; @@ -385,6 +407,8 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) gss_release_buffer(&minor_status, &input_token); failed: + if(scred) + ber_bvfree(scred); return status; } #endif -- cgit From 63378d6f0efa4612da1aecb5dee14992ac069d0f Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 7 May 2004 02:48:03 +0000 Subject: r541: fixing segfault in winbindd caused -r527 -- looks like a bug in heimdal; also initialize some pointers (This used to be commit be74e88d9a4b74fcaf25b0816e3fa8a487c91ab5) --- source3/libads/kerberos.c | 8 ++++---- source3/libads/krb5_setpw.c | 6 +++--- source3/libads/sasl.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 70f6f3386c..e8bf4b0846 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -56,9 +56,9 @@ kerb_prompter(krb5_context ctx, void *data, */ int kerberos_kinit_password(const char *principal, const char *password, int time_offset, time_t *expire_time) { - krb5_context ctx; + krb5_context ctx = NULL; krb5_error_code code = 0; - krb5_ccache cc; + krb5_ccache cc = NULL; krb5_principal me; krb5_creds my_creds; @@ -142,8 +142,8 @@ int ads_kinit_password(ADS_STRUCT *ads) int ads_kdestroy(const char *cc_name) { krb5_error_code code; - krb5_context ctx; - krb5_ccache cc; + krb5_context ctx = NULL; + krb5_ccache cc = NULL; if ((code = krb5_init_context (&ctx))) { DEBUG(3, ("ads_kdestroy: kdb5_init_context rc=%d\n", code)); diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 16d3df83e9..5c859f0e99 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -463,12 +463,12 @@ ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ, ADS_STATUS aret; krb5_error_code ret; - krb5_context context; + krb5_context context = NULL; krb5_principal principal; char *princ_name; char *realm; krb5_creds creds, *credsp; - krb5_ccache ccache; + krb5_ccache ccache = NULL; ret = krb5_init_context(&context); if (ret) { @@ -578,7 +578,7 @@ static ADS_STATUS ads_krb5_chg_password(const char *kdc_host, { ADS_STATUS aret; krb5_error_code ret; - krb5_context context; + krb5_context context = NULL; krb5_principal princ; krb5_get_init_creds_opt opts; krb5_creds creds; diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 971156ae61..18cbb46588 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -273,7 +273,7 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) unsigned sec_layer; ADS_STATUS status; krb5_principal principal; - krb5_context ctx; + krb5_context ctx = NULL; krb5_enctype enc_types[] = { #ifdef ENCTYPE_ARCFOUR_HMAC ENCTYPE_ARCFOUR_HMAC, -- cgit From a442c65e59cd0b7667087f90522883475dfb7eee Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 7 May 2004 17:58:06 +0000 Subject: r562: Memory leak fix in error code path from kawasa_r@itg.hitachi.co.jp. Jeremy. (This used to be commit ac501348f473045a7846ffd9bc6b9eb4682b8987) --- source3/libads/ldap.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 20a36dfdf5..e156857e96 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1984,15 +1984,17 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads) value = ads_pull_string(ads, ctx, res, "ldapServiceName"); if (!value) { + ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); } timestr = ads_pull_string(ads, ctx, res, "currentTime"); if (!timestr) { + ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); } - ldap_msgfree(res); + ads_msgfree(ads, res); p = strchr(value, ':'); if (!p) { @@ -2054,6 +2056,7 @@ ADS_STATUS ads_domain_sid(ADS_STRUCT *ads, DOM_SID *sid) attrs, &res); if (!ADS_ERR_OK(rc)) return rc; if (!ads_pull_sid(ads, res, "objectSid", sid)) { + ads_msgfree(ads, res); return ADS_ERROR_SYSTEM(ENOENT); } ads_msgfree(ads, res); -- cgit From 05bc3279906d63f30df1c373a50c521a171225ab Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 18 May 2004 01:05:59 +0000 Subject: r764: More memleak fixes in error code path from kawasa_r@itg.hitachi.co.jp. Jeremy. (This used to be commit 9647394e7c79c81ac4cf276a2c4b9e16eb053ec2) --- source3/libads/ldap.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index e156857e96..e018eeb2da 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1980,17 +1980,22 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads) } status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); - if (!ADS_ERR_OK(status)) return status; + if (!ADS_ERR_OK(status)) { + talloc_destroy(ctx); + return status; + } value = ads_pull_string(ads, ctx, res, "ldapServiceName"); if (!value) { ads_msgfree(ads, res); + talloc_destroy(ctx); return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); } timestr = ads_pull_string(ads, ctx, res, "currentTime"); if (!timestr) { ads_msgfree(ads, res); + talloc_destroy(ctx); return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); } -- cgit From a986d45e98f0ab2e736d9f1852c32e9dcff660d6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 17 Jun 2004 21:39:51 +0000 Subject: r1180: New file - basis of new system keytab code. Jeremy. (This used to be commit 858e849af697bba67ebaa970257d93b6cff7d9e0) --- source3/libads/kerberos_keytab.c | 434 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 434 insertions(+) create mode 100644 source3/libads/kerberos_keytab.c (limited to 'source3/libads') diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c new file mode 100644 index 0000000000..6424f742b9 --- /dev/null +++ b/source3/libads/kerberos_keytab.c @@ -0,0 +1,434 @@ +/* + Unix SMB/CIFS implementation. + kerberos keytab utility library + Copyright (C) Andrew Tridgell 2001 + Copyright (C) Remus Koos 2001 + Copyright (C) Luke Howard 2003 + Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003 + Copyright (C) Guenther Deschner 2003 + Copyright (C) Rakesh Patel 2004 + Copyright (C) Dan Perry 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +#ifdef HAVE_KRB5 + + +/* + Adds a single service principal, i.e. 'host' to the system keytab +*/ +int ads_keytab_add_entry(const char *srvPrinc, ADS_STRUCT *ads) +{ + krb5_error_code ret; + krb5_context context; + krb5_keytab keytab; + krb5_kt_cursor cursor; + krb5_keytab_entry entry; + krb5_principal princ; + krb5_data password; + krb5_enctype *enctypes = NULL; + krb5_kvno kvno; + krb5_keyblock *key; + + char *principal = NULL; + char *princ_s = NULL; + char *password_s = NULL; + char keytab_name[MAX_KEYTAB_NAME_LEN]; /* This MAX_NAME_LEN is a constant defined in krb5.h */ + fstring myname; + int i; + int retval = 0; + char *ktprinc = NULL; + struct hostent *hp; + + initialize_krb5_error_table(); + ret = krb5_init_context(&context); + if (ret) { + DEBUG(1,("could not krb5_init_context: %s\n",error_message(ret))); + return -1; + } +#ifdef HAVE_WRFILE_KEYTAB /* MIT */ + keytab_name[0] = 'W'; + keytab_name[1] = 'R'; + ret = krb5_kt_default_name(context, (char *) &keytab_name[2], MAX_KEYTAB_NAME_LEN - 4); +#else /* Heimdal */ + ret = krb5_kt_default_name(context, (char *) &keytab_name[0], MAX_KEYTAB_NAME_LEN - 2); +#endif + if (ret) { + DEBUG(1,("krb5_kt_default_name failed (%s)\n", error_message(ret))); + } + DEBUG(1,("Using default system keytab: %s\n", (char *) &keytab_name)); + ret = krb5_kt_resolve(context, (char *) &keytab_name, &keytab); + if (ret) { + DEBUG(1,("krb5_kt_resolve failed (%s)\n", error_message(ret))); + return ret; + } + + ret = get_kerberos_allowed_etypes(context,&enctypes); + if (ret) { + DEBUG(1,("get_kerberos_allowed_etypes failed (%s)\n",error_message(ret))); + goto out; + } + + /* retrieve the password */ + if (!secrets_init()) { + DEBUG(1,("secrets_init failed\n")); + ret = -1; + goto out; + } + password_s = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL); + if (!password_s) { + DEBUG(1,("failed to fetch machine password\n")); + ret = -1; + goto out; + } + password.data = password_s; + password.length = strlen(password_s); + + /* Construct our principal */ + fstrcpy(myname, global_myname()); + hp = gethostbyname(myname); + if ( hp->h_name && strlen(hp->h_name) > 0 ) { + fstrcpy(myname,hp->h_name); + } + strlower_m(myname); + asprintf(&princ_s, "%s/%s@%s", srvPrinc, myname, lp_realm()); + + ret = krb5_parse_name(context, princ_s, &princ); + if (ret) { + DEBUG(1,("krb5_parse_name(%s) failed (%s)\n", princ_s, error_message(ret))); + goto out; + } + + kvno = (krb5_kvno) ads_get_kvno(ads, global_myname()); + if (kvno == -1) { /* -1 indicates failure, everything else is OK */ + DEBUG(1,("ads_get_kvno failed to determine the system's kvno.\n")); + ret = -1; + goto out; + } + + /* Seek and delete old keytab entries */ + ret = krb5_kt_start_seq_get(context, keytab, &cursor); + if (ret != KRB5_KT_END && ret != ENOENT ) { + DEBUG(1,("Will try to delete old keytab entries\n")); + while(!krb5_kt_next_entry(context, keytab, &entry, &cursor)) { + + krb5_unparse_name(context, entry.principal, &ktprinc); + + /*--------------------------------------------------------------------------- + * Save the entries with kvno - 1. This is what microsoft does + * to allow people with existing sessions that have kvno - 1 to still + * work. Otherwise, when the password for the machine changes, all + * kerberizied sessions will 'break' until either the client reboots or + * the client's session key expires and they get a new session ticket + * with the new kvno. + */ + +#ifdef HAVE_KRB5_KT_COMPARE + if (krb5_kt_compare(context, &entry, princ, 0, 0) == True && entry.vno != kvno - 1) { +#else + if (strcmp(ktprinc, princ_s) == 0 && entry.vno != kvno - 1) { +#endif + free(ktprinc); + DEBUG(1,("Found old entry for principal: %s (kvno %d) - trying to remove it.\n", + princ_s, entry.vno)); + ret = krb5_kt_end_seq_get(context, keytab, &cursor); + if (ret) { + DEBUG(1,("krb5_kt_end_seq_get() failed (%s)\n", error_message(ret))); + goto out; + } + ret = krb5_kt_remove_entry(context, keytab, &entry); + if (ret) { + DEBUG(1,("krb5_kt_remove_entry failed (%s)\n", error_message(ret))); + goto out; + } + ret = krb5_kt_start_seq_get(context, keytab, &cursor); + if (ret) { + DEBUG(1,("krb5_kt_start_seq failed (%s)\n", error_message(ret))); + goto out; + } + ret = krb5_kt_free_entry(context, &entry); + if (ret) { + DEBUG(1,("krb5_kt_remove_entry failed (%s)\n", error_message(ret))); + goto out; + } + continue; + } else { + free(ktprinc); + } + + ret = krb5_kt_free_entry(context, &entry); + if (ret) { + DEBUG(1,("krb5_kt_free_entry failed (%s)\n", error_message(ret))); + goto out; + } + } + + ret = krb5_kt_end_seq_get(context, keytab, &cursor); + if (ret) { + DEBUG(1,("krb5_kt_end_seq_get failed (%s)\n",error_message(ret))); + goto out; + } + } + + /* Add keytab entries for all encryption types */ + for (i = 0; enctypes[i]; i++) { + + key = (krb5_keyblock *) malloc(sizeof(*key)); + if (!key) { + DEBUG(1,("Failed to allocate memory to store the keyblock.\n")); + ret = ENOMEM; + goto out; + } + + if (create_kerberos_key_from_string(context, princ, &password, key, enctypes[i])) { + continue; + } + + entry.principal = princ; + entry.vno = kvno; + +#if !defined(HAVE_KRB5_KEYTAB_ENTRY_KEY) && !defined(HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK) +#error krb5_keytab_entry has no key or keyblock member +#endif +#ifdef HAVE_KRB5_KEYTAB_ENTRY_KEY /* MIT */ + entry.key = *key; +#endif +#ifdef HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK /* Heimdal */ + entry.keyblock = *key; +#endif + DEBUG(3,("adding keytab entry for (%s) with encryption type (%d) and version (%d)\n", + princ_s, enctypes[i], entry.vno)); + ret = krb5_kt_add_entry(context, keytab, &entry); + krb5_free_keyblock(context, key); + if (ret) { + DEBUG(1,("adding entry to keytab failed (%s)\n", error_message(ret))); + krb5_kt_close(context, keytab); + goto out; + } + } + + /* Update the LDAP with the SPN */ + DEBUG(1,("Attempting to add/update '%s'\n", princ_s)); + if (!ADS_ERR_OK(ads_add_spn(ads, global_myname(), srvPrinc))) { + DEBUG(1,("ads_add_spn failed.\n")); + goto out; + } + +out: + + krb5_kt_close(context, keytab); + krb5_free_principal(context, princ); + if (enctypes) { + free(enctypes); + } + if (principal) { + free(principal); + } + if (password_s) { + free(password_s); + } + if (princ_s) { + free(princ_s); + } + + return ret; +} + + +/* + Flushes all entries from the system keytab. +*/ +int ads_keytab_flush(ADS_STRUCT *ads) +{ + krb5_error_code ret; + krb5_context context; + krb5_keytab keytab; + krb5_kt_cursor cursor; + krb5_keytab_entry entry; + krb5_kvno kvno; + char keytab_name[MAX_KEYTAB_NAME_LEN]; + + initialize_krb5_error_table(); + ret = krb5_init_context(&context); + if (ret) { + DEBUG(1,("could not krb5_init_context: %s\n",error_message(ret))); + return ret; + } +#ifdef HAVE_WRFILE_KEYTAB + keytab_name[0] = 'W'; + keytab_name[1] = 'R'; + ret = krb5_kt_default_name(context, (char *) &keytab_name[2], MAX_KEYTAB_NAME_LEN - 4); +#else + ret = krb5_kt_default_name(context, (char *) &keytab_name[0], MAX_KEYTAB_NAME_LEN - 2); +#endif + if (ret) { + DEBUG(1,("krb5_kt_default failed (%s)\n", error_message(ret))); + goto out; + } + DEBUG(1,("Using default keytab: %s\n", (char *) &keytab_name)); + ret = krb5_kt_resolve(context, (char *) &keytab_name, &keytab); + if (ret) { + DEBUG(1,("krb5_kt_default failed (%s)\n", error_message(ret))); + goto out; + } + DEBUG(1,("Using default keytab: %s\n", (char *) &keytab_name)); + ret = krb5_kt_resolve(context, (char *) &keytab_name, &keytab); + if (ret) { + DEBUG(1,("krb5_kt_default failed (%s)\n", error_message(ret))); + goto out; + } + + kvno = (krb5_kvno) ads_get_kvno(ads, global_myname()); + if (kvno == -1) { /* -1 indicates a failure */ + DEBUG(1,("Error determining the system's kvno.\n")); + goto out; + } + + ret = krb5_kt_start_seq_get(context, keytab, &cursor); + if (ret != KRB5_KT_END && ret != ENOENT) { + while (!krb5_kt_next_entry(context, keytab, &entry, &cursor)) { + ret = krb5_kt_end_seq_get(context, keytab, &cursor); + if (ret) { + DEBUG(1,("krb5_kt_end_seq_get() failed (%s)\n",error_message(ret))); + goto out; + } + ret = krb5_kt_remove_entry(context, keytab, &entry); + if (ret) { + DEBUG(1,("krb5_kt_remove_entry failed (%s)\n",error_message(ret))); + goto out; + } + ret = krb5_kt_start_seq_get(context, keytab, &cursor); + if (ret) { + DEBUG(1,("krb5_kt_start_seq failed (%s)\n",error_message(ret))); + goto out; + } + ret = krb5_kt_free_entry(context, &entry); + if (ret) { + DEBUG(1,("krb5_kt_remove_entry failed (%s)\n",error_message(ret))); + goto out; + } + } + } + if (!ADS_ERR_OK(ads_clear_spns(ads, global_myname()))) { + DEBUG(1,("Error while clearing service principal listings in LDAP.\n")); + goto out; + } + +out: + + krb5_kt_close(context, keytab); + return ret; +} + + +int ads_keytab_create_default(ADS_STRUCT *ads) +{ + krb5_error_code ret; + krb5_context context; + krb5_keytab keytab; + krb5_kt_cursor cursor; + krb5_keytab_entry entry; + krb5_kvno kvno; + char *ktprinc; + int i, found = 0; + char **oldEntries; + + ret = ads_keytab_add_entry("host", ads); + if (ret) { + DEBUG(1,("ads_keytab_add_entry failed while adding 'host'.\n")); + return ret; + } + ret = ads_keytab_add_entry("cifs", ads); + if (ret) { + DEBUG(1,("ads_keytab_add_entry failed while adding 'cifs'.\n")); + return ret; + } + + kvno = (krb5_kvno) ads_get_kvno(ads, global_myname()); + if (kvno == -1) { + DEBUG(1,("ads_get_kvno failed to determine the system's kvno.\n")); + return -1; + } + + DEBUG(1,("Searching for keytab entries to preserve and update.\n")); + /* Now loop through the keytab and update any other existing entries... */ + initialize_krb5_error_table(); + ret = krb5_init_context(&context); + if (ret) { + DEBUG(1,("could not krb5_init_context: %s\n",error_message(ret))); + return ret; + } + ret = krb5_kt_default(context, &keytab); + if (ret) { + DEBUG(1,("krb5_kt_default failed (%s)\n",error_message(ret))); + return ret; + } + + ret = krb5_kt_start_seq_get(context, keytab, &cursor); + if (ret != KRB5_KT_END && ret != ENOENT ) { + while ((ret = krb5_kt_next_entry(context, keytab, &entry, &cursor)) == 0) { + found++; + } + } + + DEBUG(1, ("Found %d entries in the keytab.\n", found)); + if (!found) { + goto done; + } + oldEntries = (char **) malloc(found * sizeof(char *)); + if (!oldEntries) { + DEBUG(1,("Failed to allocate space to store the old keytab entries (malloc failed?).\n")); + return ENOMEM; + } + memset(oldEntries, 0, found * sizeof(char *)); + + ret = krb5_kt_start_seq_get(context, keytab, &cursor); + if (ret != KRB5_KT_END && ret != ENOENT ) { + while ((ret = krb5_kt_next_entry(context, keytab, &entry, &cursor)) == 0) { + if (entry.vno != kvno) { + krb5_unparse_name(context, entry.principal, &ktprinc); + for (i = 0; *(ktprinc + i); i++) { + if (*(ktprinc + i) == '/') { + *(ktprinc + i) = (char) NULL; + break; + } + } + for (i = 0; i < found; i++) { + if (!oldEntries[i]) { + oldEntries[i] = ktprinc; + break; + } + if (!strcmp(oldEntries[i], ktprinc)) { + break; + } + } + } + } + for (i = 0; oldEntries[i]; i++) { + ret |= ads_keytab_add_entry(oldEntries[i], ads); + free(oldEntries[i]); + } + } + free(oldEntries); + +done: + + krb5_kt_close(context, keytab); + return ret; +} +#endif /* HAVE_KRB5 */ -- cgit From 920034ec3bd9612cc58d9196ac93828010c6c823 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 17 Jun 2004 23:07:20 +0000 Subject: r1182: Partial re-write of keytab code to clean up, remove memory leaks etc. Work in progress ! It seems the krb5 interfaces are so horrible it's impossible to write good error checking code :-(. Jeremy. (This used to be commit 03f8c8bc07c9d8a378a34c271dcc088d17adb342) --- source3/libads/kerberos_keytab.c | 124 ++++++++++++++++++++++++--------------- 1 file changed, 77 insertions(+), 47 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c index 6424f742b9..9fc3410e5c 100644 --- a/source3/libads/kerberos_keytab.c +++ b/source3/libads/kerberos_keytab.c @@ -8,6 +8,7 @@ Copyright (C) Guenther Deschner 2003 Copyright (C) Rakesh Patel 2004 Copyright (C) Dan Perry 2004 + Copyright (C) Jeremy Allison 2004 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -28,37 +29,52 @@ #ifdef HAVE_KRB5 +/********************************************************************** + Converts a name to a fully qalified domain name. +***********************************************************************/ -/* +void name_to_fqdn(fstring fqdn, const char *name) +{ + struct hostent *hp = sys_gethostbyname(name); + if ( hp && hp->h_name && *hp->h_name ) { + DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name, hp->h_name)); + fstrcpy(fqdn,hp->h_name); + } else { + DEBUG(10,("name_to_fqdn: lookup for %s failed.\n", name)); + fstrcpy(fqdn, name); + } +} + +/********************************************************************** Adds a single service principal, i.e. 'host' to the system keytab -*/ +***********************************************************************/ + int ads_keytab_add_entry(const char *srvPrinc, ADS_STRUCT *ads) { - krb5_error_code ret; - krb5_context context; - krb5_keytab keytab; - krb5_kt_cursor cursor; - krb5_keytab_entry entry; - krb5_principal princ; + krb5_error_code ret = 0; + krb5_context context = NULL; + krb5_keytab keytab = NULL; + krb5_kt_cursor cursor = NULL; + krb5_keytab_entry kt_entry; + krb5_principal princ = NULL; krb5_data password; krb5_enctype *enctypes = NULL; krb5_kvno kvno; - krb5_keyblock *key; + krb5_keyblock *key = NULL; char *principal = NULL; char *princ_s = NULL; char *password_s = NULL; char keytab_name[MAX_KEYTAB_NAME_LEN]; /* This MAX_NAME_LEN is a constant defined in krb5.h */ - fstring myname; + fstring my_fqdn; int i; - int retval = 0; char *ktprinc = NULL; - struct hostent *hp; + ZERO_STRUCT(kt_entry); initialize_krb5_error_table(); ret = krb5_init_context(&context); if (ret) { - DEBUG(1,("could not krb5_init_context: %s\n",error_message(ret))); + DEBUG(1,("ads_keytab_add_entry: could not krb5_init_context: %s\n",error_message(ret))); return -1; } #ifdef HAVE_WRFILE_KEYTAB /* MIT */ @@ -69,30 +85,31 @@ int ads_keytab_add_entry(const char *srvPrinc, ADS_STRUCT *ads) ret = krb5_kt_default_name(context, (char *) &keytab_name[0], MAX_KEYTAB_NAME_LEN - 2); #endif if (ret) { - DEBUG(1,("krb5_kt_default_name failed (%s)\n", error_message(ret))); + DEBUG(1,("ads_keytab_add_entry: krb5_kt_default_name failed (%s)\n", error_message(ret))); + goto out; } - DEBUG(1,("Using default system keytab: %s\n", (char *) &keytab_name)); + DEBUG(2,("ads_keytab_add_entry: Using default system keytab: %s\n", (char *) &keytab_name)); ret = krb5_kt_resolve(context, (char *) &keytab_name, &keytab); if (ret) { - DEBUG(1,("krb5_kt_resolve failed (%s)\n", error_message(ret))); - return ret; + DEBUG(1,("ads_keytab_add_entry: krb5_kt_resolve failed (%s)\n", error_message(ret))); + goto out; } ret = get_kerberos_allowed_etypes(context,&enctypes); if (ret) { - DEBUG(1,("get_kerberos_allowed_etypes failed (%s)\n",error_message(ret))); + DEBUG(1,("ads_keytab_add_entry: get_kerberos_allowed_etypes failed (%s)\n",error_message(ret))); goto out; } /* retrieve the password */ if (!secrets_init()) { - DEBUG(1,("secrets_init failed\n")); + DEBUG(1,("ads_keytab_add_entry: secrets_init failed\n")); ret = -1; goto out; } password_s = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL); if (!password_s) { - DEBUG(1,("failed to fetch machine password\n")); + DEBUG(1,("ads_keytab_add_entry: failed to fetch machine password\n")); ret = -1; goto out; } @@ -100,23 +117,19 @@ int ads_keytab_add_entry(const char *srvPrinc, ADS_STRUCT *ads) password.length = strlen(password_s); /* Construct our principal */ - fstrcpy(myname, global_myname()); - hp = gethostbyname(myname); - if ( hp->h_name && strlen(hp->h_name) > 0 ) { - fstrcpy(myname,hp->h_name); - } - strlower_m(myname); - asprintf(&princ_s, "%s/%s@%s", srvPrinc, myname, lp_realm()); + name_to_fqdn(my_fqdn, global_myname()); + strlower_m(my_fqdn); + asprintf(&princ_s, "%s/%s@%s", srvPrinc, my_fqdn, lp_realm()); ret = krb5_parse_name(context, princ_s, &princ); if (ret) { - DEBUG(1,("krb5_parse_name(%s) failed (%s)\n", princ_s, error_message(ret))); + DEBUG(1,("ads_keytab_add_entry: krb5_parse_name(%s) failed (%s)\n", princ_s, error_message(ret))); goto out; } kvno = (krb5_kvno) ads_get_kvno(ads, global_myname()); if (kvno == -1) { /* -1 indicates failure, everything else is OK */ - DEBUG(1,("ads_get_kvno failed to determine the system's kvno.\n")); + DEBUG(1,("ads_keytab_add_entry: ads_get_kvno failed to determine the system's kvno.\n")); ret = -1; goto out; } @@ -124,10 +137,14 @@ int ads_keytab_add_entry(const char *srvPrinc, ADS_STRUCT *ads) /* Seek and delete old keytab entries */ ret = krb5_kt_start_seq_get(context, keytab, &cursor); if (ret != KRB5_KT_END && ret != ENOENT ) { - DEBUG(1,("Will try to delete old keytab entries\n")); - while(!krb5_kt_next_entry(context, keytab, &entry, &cursor)) { + DEBUG(3,("ads_keytab_add_entry: Will try to delete old keytab entries\n")); + while(!krb5_kt_next_entry(context, keytab, &kt_entry, &cursor)) { - krb5_unparse_name(context, entry.principal, &ktprinc); + ret = krb5_unparse_name(context, entry.principal, &ktprinc); + if (ret) { + DEBUG(1,("ads_keytab_add_entry: krb5_unparse_name failed (%s)\n", error_message(ret))); + goto out; + } /*--------------------------------------------------------------------------- * Save the entries with kvno - 1. This is what microsoft does @@ -138,12 +155,14 @@ int ads_keytab_add_entry(const char *srvPrinc, ADS_STRUCT *ads) * with the new kvno. */ + HERE + #ifdef HAVE_KRB5_KT_COMPARE - if (krb5_kt_compare(context, &entry, princ, 0, 0) == True && entry.vno != kvno - 1) { + if (krb5_kt_compare(context, &kt_entry, princ, 0, 0) == True && kt_entry.vno != kvno - 1) { #else - if (strcmp(ktprinc, princ_s) == 0 && entry.vno != kvno - 1) { + if (strcmp(ktprinc, princ_s) == 0 && kt_entry.vno != kvno - 1) { #endif - free(ktprinc); + SAFE_FREE(ktprinc); DEBUG(1,("Found old entry for principal: %s (kvno %d) - trying to remove it.\n", princ_s, entry.vno)); ret = krb5_kt_end_seq_get(context, keytab, &cursor); @@ -168,7 +187,7 @@ int ads_keytab_add_entry(const char *srvPrinc, ADS_STRUCT *ads) } continue; } else { - free(ktprinc); + SAFE_FREE(ktprinc); } ret = krb5_kt_free_entry(context, &entry); @@ -231,22 +250,33 @@ int ads_keytab_add_entry(const char *srvPrinc, ADS_STRUCT *ads) out: - krb5_kt_close(context, keytab); - krb5_free_principal(context, princ); + SAFE_FREE(principal); + SAFE_FREE(password_s); + SAFE_FREE(princ_s); + + { + krb5_keytab_entry zero_kt_entry; + ZERO_STRUCT(zero_kt_entry); + if (memcmp(&zero_kt_entry, &kt_entry, sizeof(krb5_keytab_entry))) { + krb5_kt_free_entry(context, &kt_entry); + } + } + if (princ) { + krb5_free_principal(context, princ); + } if (enctypes) { - free(enctypes); + free_kerberos_etypes(context, enctypes); } - if (principal) { - free(principal); + if (cursor && keytab) { + krb5_kt_end_seq_get(context, keytab, &cursor); } - if (password_s) { - free(password_s); + if (keytab) { + krb5_kt_close(context, keytab); } - if (princ_s) { - free(princ_s); + if (context) { + krb5_free_context(context); } - - return ret; + return (int)ret; } -- cgit From 04257821e9cd92998a227ca3391fe350c497e6b1 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 18 Jun 2004 00:24:53 +0000 Subject: r1183: Updates to the code cleanup so I don't lose my changes... Jeremy. (This used to be commit 786a440c189556d5c122b2c9ddca9fdf6bd65d1d) --- source3/libads/kerberos_keytab.c | 114 +++++++++++++++++++++------------------ 1 file changed, 62 insertions(+), 52 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c index 9fc3410e5c..97e68f2bcb 100644 --- a/source3/libads/kerberos_keytab.c +++ b/source3/libads/kerberos_keytab.c @@ -60,7 +60,6 @@ int ads_keytab_add_entry(const char *srvPrinc, ADS_STRUCT *ads) krb5_data password; krb5_enctype *enctypes = NULL; krb5_kvno kvno; - krb5_keyblock *key = NULL; char *principal = NULL; char *princ_s = NULL; @@ -95,12 +94,6 @@ int ads_keytab_add_entry(const char *srvPrinc, ADS_STRUCT *ads) goto out; } - ret = get_kerberos_allowed_etypes(context,&enctypes); - if (ret) { - DEBUG(1,("ads_keytab_add_entry: get_kerberos_allowed_etypes failed (%s)\n",error_message(ret))); - goto out; - } - /* retrieve the password */ if (!secrets_init()) { DEBUG(1,("ads_keytab_add_entry: secrets_init failed\n")); @@ -139,8 +132,9 @@ int ads_keytab_add_entry(const char *srvPrinc, ADS_STRUCT *ads) if (ret != KRB5_KT_END && ret != ENOENT ) { DEBUG(3,("ads_keytab_add_entry: Will try to delete old keytab entries\n")); while(!krb5_kt_next_entry(context, keytab, &kt_entry, &cursor)) { + BOOL compare_ok = False; - ret = krb5_unparse_name(context, entry.principal, &ktprinc); + ret = krb5_unparse_name(context, kt_entry.principal, &ktprinc); if (ret) { DEBUG(1,("ads_keytab_add_entry: krb5_unparse_name failed (%s)\n", error_message(ret))); goto out; @@ -155,96 +149,112 @@ int ads_keytab_add_entry(const char *srvPrinc, ADS_STRUCT *ads) * with the new kvno. */ - HERE - #ifdef HAVE_KRB5_KT_COMPARE - if (krb5_kt_compare(context, &kt_entry, princ, 0, 0) == True && kt_entry.vno != kvno - 1) { + compare_ok = ((krb5_kt_compare(context, &kt_entry, princ, 0, 0) == True) && (kt_entry.vno != kvno - 1)); #else - if (strcmp(ktprinc, princ_s) == 0 && kt_entry.vno != kvno - 1) { + compare_ok = ((strcmp(ktprinc, princ_s) == 0) && (kt_entry.vno != kvno - 1)); #endif - SAFE_FREE(ktprinc); - DEBUG(1,("Found old entry for principal: %s (kvno %d) - trying to remove it.\n", - princ_s, entry.vno)); + SAFE_FREE(ktprinc); + + if (compare_ok) { + DEBUG(3,("ads_keytab_add_entry: Found old entry for principal: %s (kvno %d) - trying to remove it.\n", + princ_s, kt_entry.vno)); ret = krb5_kt_end_seq_get(context, keytab, &cursor); + cursor = NULL; if (ret) { - DEBUG(1,("krb5_kt_end_seq_get() failed (%s)\n", error_message(ret))); + DEBUG(1,("ads_keytab_add_entry: krb5_kt_end_seq_get() failed (%s)\n", + error_message(ret))); goto out; } - ret = krb5_kt_remove_entry(context, keytab, &entry); + ret = krb5_kt_remove_entry(context, keytab, &kt_entry); if (ret) { - DEBUG(1,("krb5_kt_remove_entry failed (%s)\n", error_message(ret))); + DEBUG(1,("ads_keytab_add_entry: krb5_kt_remove_entry failed (%s)\n", + error_message(ret))); goto out; } ret = krb5_kt_start_seq_get(context, keytab, &cursor); if (ret) { - DEBUG(1,("krb5_kt_start_seq failed (%s)\n", error_message(ret))); + DEBUG(1,("ads_keytab_add_entry: krb5_kt_start_seq failed (%s)\n", + error_message(ret))); goto out; } - ret = krb5_kt_free_entry(context, &entry); + ret = krb5_kt_free_entry(context, &kt_entry); + ZERO_STRUCT(kt_entry); if (ret) { - DEBUG(1,("krb5_kt_remove_entry failed (%s)\n", error_message(ret))); + DEBUG(1,("ads_keytab_add_entry: krb5_kt_remove_entry failed (%s)\n", + error_message(ret))); goto out; } continue; - } else { - SAFE_FREE(ktprinc); } - ret = krb5_kt_free_entry(context, &entry); + /* Not a match, just free this entry and continue. */ + ret = krb5_kt_free_entry(context, &kt_entry); + ZERO_STRUCT(kt_entry); if (ret) { - DEBUG(1,("krb5_kt_free_entry failed (%s)\n", error_message(ret))); + DEBUG(1,("ads_keytab_add_entry: krb5_kt_free_entry failed (%s)\n", error_message(ret))); goto out; } } ret = krb5_kt_end_seq_get(context, keytab, &cursor); + cursor = NULL; if (ret) { - DEBUG(1,("krb5_kt_end_seq_get failed (%s)\n",error_message(ret))); + DEBUG(1,("ads_keytab_add_entry: krb5_kt_end_seq_get failed (%s)\n",error_message(ret))); goto out; } } - /* Add keytab entries for all encryption types */ - for (i = 0; enctypes[i]; i++) { + /* Ensure we don't double free. */ + ZERO_STRUCT(kt_entry); + cursor = NULL; - key = (krb5_keyblock *) malloc(sizeof(*key)); - if (!key) { - DEBUG(1,("Failed to allocate memory to store the keyblock.\n")); - ret = ENOMEM; - goto out; - } + /* If we get here, we have deleted all the old entries with kvno's not equal to the current kvno-1. */ - if (create_kerberos_key_from_string(context, princ, &password, key, enctypes[i])) { - continue; - } + ret = get_kerberos_allowed_etypes(context,&enctypes); + if (ret) { + DEBUG(1,("ads_keytab_add_entry: get_kerberos_allowed_etypes failed (%s)\n",error_message(ret))); + goto out; + } - entry.principal = princ; - entry.vno = kvno; + /* Now add keytab entries for all encryption types */ + for (i = 0; enctypes[i]; i++) { + krb5_keyblock *keyp; #if !defined(HAVE_KRB5_KEYTAB_ENTRY_KEY) && !defined(HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK) #error krb5_keytab_entry has no key or keyblock member #endif #ifdef HAVE_KRB5_KEYTAB_ENTRY_KEY /* MIT */ - entry.key = *key; + keyp = &kt_entry.key; #endif #ifdef HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK /* Heimdal */ - entry.keyblock = *key; + keyp = &kt_entry.keyblock; #endif - DEBUG(3,("adding keytab entry for (%s) with encryption type (%d) and version (%d)\n", - princ_s, enctypes[i], entry.vno)); - ret = krb5_kt_add_entry(context, keytab, &entry); - krb5_free_keyblock(context, key); + if (create_kerberos_key_from_string(context, princ, &password, keyp, enctypes[i])) { + continue; + } + + kt_entry.principal = princ; + kt_entry.vno = kvno; + + DEBUG(3,("ads_keytab_add_entry: adding keytab entry for (%s) with encryption type (%d) and version (%d)\n", + princ_s, enctypes[i], kt_entry.vno)); + ret = krb5_kt_add_entry(context, keytab, &kt_entry); + krb5_free_keyblock(context, keyp); + ZERO_STRUCT(kt_entry); if (ret) { - DEBUG(1,("adding entry to keytab failed (%s)\n", error_message(ret))); - krb5_kt_close(context, keytab); + DEBUG(1,("ads_keytab_add_entry: adding entry to keytab failed (%s)\n", error_message(ret))); goto out; } } + krb5_kt_close(context, keytab); + keytab = NULL; /* Done with keytab now. No double free. */ + /* Update the LDAP with the SPN */ - DEBUG(1,("Attempting to add/update '%s'\n", princ_s)); + DEBUG(3,("ads_keytab_add_entry: Attempting to add/update '%s'\n", princ_s)); if (!ADS_ERR_OK(ads_add_spn(ads, global_myname(), srvPrinc))) { - DEBUG(1,("ads_add_spn failed.\n")); + DEBUG(1,("ads_keytab_add_entry: ads_add_spn failed.\n")); goto out; } @@ -279,10 +289,10 @@ out: return (int)ret; } - -/* +/********************************************************************** Flushes all entries from the system keytab. -*/ +***********************************************************************/ + int ads_keytab_flush(ADS_STRUCT *ads) { krb5_error_code ret; -- cgit From 92fea615f562b3a146c7694473025bf00f997854 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 18 Jun 2004 02:07:42 +0000 Subject: r1184: Keep latest changes... not compilable yet. Jeremy. (This used to be commit 57c037c6c92d28b70e36859a639c53979126ff01) --- source3/libads/kerberos_keytab.c | 43 ++++++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 13 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c index 97e68f2bcb..ec44bfbe68 100644 --- a/source3/libads/kerberos_keytab.c +++ b/source3/libads/kerberos_keytab.c @@ -295,18 +295,19 @@ out: int ads_keytab_flush(ADS_STRUCT *ads) { - krb5_error_code ret; - krb5_context context; - krb5_keytab keytab; - krb5_kt_cursor cursor; - krb5_keytab_entry entry; + krb5_error_code ret = 0; + krb5_context context = NULL; + krb5_keytab keytab = NULL; + krb5_kt_cursor cursor = NULL; + krb5_keytab_entry kt_entry; krb5_kvno kvno; char keytab_name[MAX_KEYTAB_NAME_LEN]; + ZERO_STRUCT(kt_entry); initialize_krb5_error_table(); ret = krb5_init_context(&context); if (ret) { - DEBUG(1,("could not krb5_init_context: %s\n",error_message(ret))); + DEBUG(1,("ads_keytab_flush: could not krb5_init_context: %s\n",error_message(ret))); return ret; } #ifdef HAVE_WRFILE_KEYTAB @@ -317,28 +318,29 @@ int ads_keytab_flush(ADS_STRUCT *ads) ret = krb5_kt_default_name(context, (char *) &keytab_name[0], MAX_KEYTAB_NAME_LEN - 2); #endif if (ret) { - DEBUG(1,("krb5_kt_default failed (%s)\n", error_message(ret))); + DEBUG(1,("ads_keytab_flush: krb5_kt_default failed (%s)\n", error_message(ret))); goto out; } - DEBUG(1,("Using default keytab: %s\n", (char *) &keytab_name)); + DEBUG(3,("ads_keytab_flush: Using default keytab: %s\n", (char *) &keytab_name)); ret = krb5_kt_resolve(context, (char *) &keytab_name, &keytab); if (ret) { - DEBUG(1,("krb5_kt_default failed (%s)\n", error_message(ret))); + DEBUG(1,("ads_keytab_flush: krb5_kt_default failed (%s)\n", error_message(ret))); goto out; } - DEBUG(1,("Using default keytab: %s\n", (char *) &keytab_name)); ret = krb5_kt_resolve(context, (char *) &keytab_name, &keytab); if (ret) { - DEBUG(1,("krb5_kt_default failed (%s)\n", error_message(ret))); + DEBUG(1,("ads_keytab_flush: krb5_kt_default failed (%s)\n", error_message(ret))); goto out; } kvno = (krb5_kvno) ads_get_kvno(ads, global_myname()); if (kvno == -1) { /* -1 indicates a failure */ - DEBUG(1,("Error determining the system's kvno.\n")); + DEBUG(1,("ads_keytab_flush: Error determining the system's kvno.\n")); goto out; } +HERE + ret = krb5_kt_start_seq_get(context, keytab, &cursor); if (ret != KRB5_KT_END && ret != ENOENT) { while (!krb5_kt_next_entry(context, keytab, &entry, &cursor)) { @@ -371,7 +373,22 @@ int ads_keytab_flush(ADS_STRUCT *ads) out: - krb5_kt_close(context, keytab); + { + krb5_keytab_entry zero_kt_entry; + ZERO_STRUCT(zero_kt_entry); + if (memcmp(&zero_kt_entry, &kt_entry, sizeof(krb5_keytab_entry))) { + krb5_kt_free_entry(context, &kt_entry); + } + } + if (cursor && keytab) { + krb5_kt_end_seq_get(context, keytab, &cursor); + } + if (keytab) { + krb5_kt_close(context, keytab); + } + if (context) { + krb5_free_context(context); + } return ret; } -- cgit From d703c350cbbd04d7cea79575dc1bfec284cb1cb5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 18 Jun 2004 23:15:42 +0000 Subject: r1192: Fixed all memleaks/error code return path leaks I can find. Not sure if compiles yet, but will soon :-). Jeremy. (This used to be commit 0d982956f6ba2f284ffa4313a9e7581a79dbf397) --- source3/libads/kerberos_keytab.c | 136 +++++++++++++++++++++++++++------------ 1 file changed, 94 insertions(+), 42 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c index ec44bfbe68..95ff0c1cf3 100644 --- a/source3/libads/kerberos_keytab.c +++ b/source3/libads/kerberos_keytab.c @@ -46,7 +46,7 @@ void name_to_fqdn(fstring fqdn, const char *name) } /********************************************************************** - Adds a single service principal, i.e. 'host' to the system keytab + Adds a single service principal, i.e. 'host' to the system keytab ***********************************************************************/ int ads_keytab_add_entry(const char *srvPrinc, ADS_STRUCT *ads) @@ -290,7 +290,7 @@ out: } /********************************************************************** - Flushes all entries from the system keytab. + Flushes all entries from the system keytab. ***********************************************************************/ int ads_keytab_flush(ADS_STRUCT *ads) @@ -339,35 +339,40 @@ int ads_keytab_flush(ADS_STRUCT *ads) goto out; } -HERE - ret = krb5_kt_start_seq_get(context, keytab, &cursor); if (ret != KRB5_KT_END && ret != ENOENT) { - while (!krb5_kt_next_entry(context, keytab, &entry, &cursor)) { + while (!krb5_kt_next_entry(context, keytab, &kt_entry, &cursor)) { ret = krb5_kt_end_seq_get(context, keytab, &cursor); + cursor = NULL; if (ret) { - DEBUG(1,("krb5_kt_end_seq_get() failed (%s)\n",error_message(ret))); + DEBUG(1,("ads_keytab_flush: krb5_kt_end_seq_get() failed (%s)\n",error_message(ret))); goto out; } - ret = krb5_kt_remove_entry(context, keytab, &entry); + ret = krb5_kt_remove_entry(context, keytab, &kt_entry); if (ret) { - DEBUG(1,("krb5_kt_remove_entry failed (%s)\n",error_message(ret))); + DEBUG(1,("ads_keytab_flush: krb5_kt_remove_entry failed (%s)\n",error_message(ret))); goto out; } ret = krb5_kt_start_seq_get(context, keytab, &cursor); if (ret) { - DEBUG(1,("krb5_kt_start_seq failed (%s)\n",error_message(ret))); + DEBUG(1,("ads_keytab_flush: krb5_kt_start_seq failed (%s)\n",error_message(ret))); goto out; } - ret = krb5_kt_free_entry(context, &entry); + ret = krb5_kt_free_entry(context, &kt_entry); + ZERO_STRUCT(kt_entry); if (ret) { - DEBUG(1,("krb5_kt_remove_entry failed (%s)\n",error_message(ret))); + DEBUG(1,("ads_keytab_flush: krb5_kt_remove_entry failed (%s)\n",error_message(ret))); goto out; } } } + + /* Ensure we don't double free. */ + ZERO_STRUCT(kt_entry); + cursor = NULL; + if (!ADS_ERR_OK(ads_clear_spns(ads, global_myname()))) { - DEBUG(1,("Error while clearing service principal listings in LDAP.\n")); + DEBUG(1,("ads_keytab_flush: Error while clearing service principal listings in LDAP.\n")); goto out; } @@ -392,78 +397,105 @@ out: return ret; } +/********************************************************************** + Adds all the required service principals to the system keytab. +***********************************************************************/ int ads_keytab_create_default(ADS_STRUCT *ads) { - krb5_error_code ret; - krb5_context context; - krb5_keytab keytab; - krb5_kt_cursor cursor; - krb5_keytab_entry entry; + krb5_error_code ret = 0; + krb5_context context = NULL; + krb5_keytab keytab = NULL; + krb5_kt_cursor cursor = NULL; + krb5_keytab_entry kt_entry; krb5_kvno kvno; - char *ktprinc; int i, found = 0; - char **oldEntries; + char **oldEntries = NULL; ret = ads_keytab_add_entry("host", ads); if (ret) { - DEBUG(1,("ads_keytab_add_entry failed while adding 'host'.\n")); + DEBUG(1,("ads_keytab_create_default: ads_keytab_add_entry failed while adding 'host'.\n")); return ret; } ret = ads_keytab_add_entry("cifs", ads); if (ret) { - DEBUG(1,("ads_keytab_add_entry failed while adding 'cifs'.\n")); + DEBUG(1,("ads_keytab_create_default: ads_keytab_add_entry failed while adding 'cifs'.\n")); return ret; } kvno = (krb5_kvno) ads_get_kvno(ads, global_myname()); if (kvno == -1) { - DEBUG(1,("ads_get_kvno failed to determine the system's kvno.\n")); + DEBUG(1,("ads_keytab_create_default: ads_get_kvno failed to determine the system's kvno.\n")); return -1; } - DEBUG(1,("Searching for keytab entries to preserve and update.\n")); + DEBUG(3,("ads_keytab_create_default: Searching for keytab entries to preserve and update.\n")); /* Now loop through the keytab and update any other existing entries... */ + + ZERO_STRUCT(kt_entry); + initialize_krb5_error_table(); ret = krb5_init_context(&context); if (ret) { - DEBUG(1,("could not krb5_init_context: %s\n",error_message(ret))); + DEBUG(1,("ads_keytab_create_default: could not krb5_init_context: %s\n",error_message(ret))); return ret; } ret = krb5_kt_default(context, &keytab); if (ret) { - DEBUG(1,("krb5_kt_default failed (%s)\n",error_message(ret))); - return ret; + DEBUG(1,("ads_keytab_create_default: krb5_kt_default failed (%s)\n",error_message(ret))); + goto done; } ret = krb5_kt_start_seq_get(context, keytab, &cursor); if (ret != KRB5_KT_END && ret != ENOENT ) { - while ((ret = krb5_kt_next_entry(context, keytab, &entry, &cursor)) == 0) { + while ((ret = krb5_kt_next_entry(context, keytab, &kt_entry, &cursor)) == 0) { + krb5_kt_free_entry(context, &kt_entry); + ZERO_STRUCT(kt_entry); found++; } } + krb5_kt_end_seq_get(context, keytab, &cursor); + cursor = NULL; - DEBUG(1, ("Found %d entries in the keytab.\n", found)); + /* + * Hmmm. There is no "rewind" function for the keytab. This means we have a race condition + * where someone else could add entries after we've counted them. Re-open asap to minimise + * the race. JRA. + */ + + DEBUG(3, ("ads_keytab_create_default: Found %d entries in the keytab.\n", found)); if (!found) { goto done; } oldEntries = (char **) malloc(found * sizeof(char *)); if (!oldEntries) { - DEBUG(1,("Failed to allocate space to store the old keytab entries (malloc failed?).\n")); - return ENOMEM; + DEBUG(1,("ads_keytab_create_default: Failed to allocate space to store the old keytab entries (malloc failed?).\n")); + ret = -1; + goto done; } - memset(oldEntries, 0, found * sizeof(char *)); + memset(oldEntries, '\0', found * sizeof(char *)); ret = krb5_kt_start_seq_get(context, keytab, &cursor); if (ret != KRB5_KT_END && ret != ENOENT ) { - while ((ret = krb5_kt_next_entry(context, keytab, &entry, &cursor)) == 0) { - if (entry.vno != kvno) { - krb5_unparse_name(context, entry.principal, &ktprinc); - for (i = 0; *(ktprinc + i); i++) { - if (*(ktprinc + i) == '/') { - *(ktprinc + i) = (char) NULL; - break; - } + while ((ret = krb5_kt_next_entry(context, keytab, &kt_entry, &cursor)) == 0) { + if (kt_entry.vno != kvno) { + char *ktprinc; + char *p; + + /* This returns a malloc'ed string in ktprinc. */ + ret = krb5_unparse_name(context, kt_entry.principal, &ktprinc); + if (ret) { + DEBUG(1,("krb5_unparse_name failed (%s)\n", error_message(ret))); + goto out; + } + /* + * From looking at the krb5 source they don't seem to take locale + * or mb strings into account. Maybe this is because they assume utf8 ? + * In this case we may need to convert from utf8 to mb charset here ? JRA. + */ + p = strchr_m(ktprinc, '/'); + if (p) { + *p = '\0'; } for (i = 0; i < found; i++) { if (!oldEntries[i]) { @@ -475,17 +507,37 @@ int ads_keytab_create_default(ADS_STRUCT *ads) } } } + krb5_kt_free_entry(context, &kt_entry); + ZERO_STRUCT(kt_entry); } for (i = 0; oldEntries[i]; i++) { ret |= ads_keytab_add_entry(oldEntries[i], ads); - free(oldEntries[i]); + SAFE_FREE(oldEntries[i]); } + krb5_kt_end_seq_get(context, keytab, &cursor); } - free(oldEntries); + cursor = NULL; done: - krb5_kt_close(context, keytab); + SAFE_FREE(oldEntries); + + { + krb5_keytab_entry zero_kt_entry; + ZERO_STRUCT(zero_kt_entry); + if (memcmp(&zero_kt_entry, &kt_entry, sizeof(krb5_keytab_entry))) { + krb5_kt_free_entry(context, &kt_entry); + } + } + if (cursor && keytab) { + krb5_kt_end_seq_get(context, keytab, &cursor); + } + if (keytab) { + krb5_kt_close(context, keytab); + } + if (context) { + krb5_free_context(context); + } return ret; } #endif /* HAVE_KRB5 */ -- cgit From f38c27b4e092f5846bf1b547405df68e4bf3391d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 19 Jun 2004 00:54:54 +0000 Subject: r1193: Ensure we check for and use krb5_free_unparsed_name(). Jeremy. (This used to be commit af5a08f5ad895cb33c9134771da19ba5e709e742) --- source3/libads/kerberos_keytab.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c index 95ff0c1cf3..605c7e1b1a 100644 --- a/source3/libads/kerberos_keytab.c +++ b/source3/libads/kerberos_keytab.c @@ -154,7 +154,8 @@ int ads_keytab_add_entry(const char *srvPrinc, ADS_STRUCT *ads) #else compare_ok = ((strcmp(ktprinc, princ_s) == 0) && (kt_entry.vno != kvno - 1)); #endif - SAFE_FREE(ktprinc); + krb5_free_unparsed_name(ktprinc); + ktprinc = NULL; if (compare_ok) { DEBUG(3,("ads_keytab_add_entry: Found old entry for principal: %s (kvno %d) - trying to remove it.\n", @@ -479,7 +480,7 @@ int ads_keytab_create_default(ADS_STRUCT *ads) if (ret != KRB5_KT_END && ret != ENOENT ) { while ((ret = krb5_kt_next_entry(context, keytab, &kt_entry, &cursor)) == 0) { if (kt_entry.vno != kvno) { - char *ktprinc; + char *ktprinc = NULL; char *p; /* This returns a malloc'ed string in ktprinc. */ @@ -512,7 +513,7 @@ int ads_keytab_create_default(ADS_STRUCT *ads) } for (i = 0; oldEntries[i]; i++) { ret |= ads_keytab_add_entry(oldEntries[i], ads); - SAFE_FREE(oldEntries[i]); + krb5_free_unparsed_name(oldEntries[i]); } krb5_kt_end_seq_get(context, keytab, &cursor); } -- cgit From 5a889c9d7bd3d66d6bbb5d31eb320f2e2f555d60 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 21 Jun 2004 19:10:25 +0000 Subject: r1214: Now compiles. Changed krb5_kt_free_entry to krb5_free_keytab_entry_contents Jeremy. (This used to be commit be8a2dc00dd876c4b596600ae72d4ac05f9ebe64) --- source3/libads/kerberos_keytab.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c index 605c7e1b1a..dc25fb74c0 100644 --- a/source3/libads/kerberos_keytab.c +++ b/source3/libads/kerberos_keytab.c @@ -154,7 +154,7 @@ int ads_keytab_add_entry(const char *srvPrinc, ADS_STRUCT *ads) #else compare_ok = ((strcmp(ktprinc, princ_s) == 0) && (kt_entry.vno != kvno - 1)); #endif - krb5_free_unparsed_name(ktprinc); + krb5_free_unparsed_name(context, ktprinc); ktprinc = NULL; if (compare_ok) { @@ -179,7 +179,7 @@ int ads_keytab_add_entry(const char *srvPrinc, ADS_STRUCT *ads) error_message(ret))); goto out; } - ret = krb5_kt_free_entry(context, &kt_entry); + ret = krb5_free_keytab_entry_contents(context, &kt_entry); ZERO_STRUCT(kt_entry); if (ret) { DEBUG(1,("ads_keytab_add_entry: krb5_kt_remove_entry failed (%s)\n", @@ -190,10 +190,10 @@ int ads_keytab_add_entry(const char *srvPrinc, ADS_STRUCT *ads) } /* Not a match, just free this entry and continue. */ - ret = krb5_kt_free_entry(context, &kt_entry); + ret = krb5_free_keytab_entry_contents(context, &kt_entry); ZERO_STRUCT(kt_entry); if (ret) { - DEBUG(1,("ads_keytab_add_entry: krb5_kt_free_entry failed (%s)\n", error_message(ret))); + DEBUG(1,("ads_keytab_add_entry: krb5_free_keytab_entry_contents failed (%s)\n", error_message(ret))); goto out; } } @@ -269,7 +269,7 @@ out: krb5_keytab_entry zero_kt_entry; ZERO_STRUCT(zero_kt_entry); if (memcmp(&zero_kt_entry, &kt_entry, sizeof(krb5_keytab_entry))) { - krb5_kt_free_entry(context, &kt_entry); + krb5_free_keytab_entry_contents(context, &kt_entry); } } if (princ) { @@ -359,7 +359,7 @@ int ads_keytab_flush(ADS_STRUCT *ads) DEBUG(1,("ads_keytab_flush: krb5_kt_start_seq failed (%s)\n",error_message(ret))); goto out; } - ret = krb5_kt_free_entry(context, &kt_entry); + ret = krb5_free_keytab_entry_contents(context, &kt_entry); ZERO_STRUCT(kt_entry); if (ret) { DEBUG(1,("ads_keytab_flush: krb5_kt_remove_entry failed (%s)\n",error_message(ret))); @@ -383,7 +383,7 @@ out: krb5_keytab_entry zero_kt_entry; ZERO_STRUCT(zero_kt_entry); if (memcmp(&zero_kt_entry, &kt_entry, sizeof(krb5_keytab_entry))) { - krb5_kt_free_entry(context, &kt_entry); + krb5_free_keytab_entry_contents(context, &kt_entry); } } if (cursor && keytab) { @@ -450,7 +450,7 @@ int ads_keytab_create_default(ADS_STRUCT *ads) ret = krb5_kt_start_seq_get(context, keytab, &cursor); if (ret != KRB5_KT_END && ret != ENOENT ) { while ((ret = krb5_kt_next_entry(context, keytab, &kt_entry, &cursor)) == 0) { - krb5_kt_free_entry(context, &kt_entry); + krb5_free_keytab_entry_contents(context, &kt_entry); ZERO_STRUCT(kt_entry); found++; } @@ -487,7 +487,7 @@ int ads_keytab_create_default(ADS_STRUCT *ads) ret = krb5_unparse_name(context, kt_entry.principal, &ktprinc); if (ret) { DEBUG(1,("krb5_unparse_name failed (%s)\n", error_message(ret))); - goto out; + goto done; } /* * From looking at the krb5 source they don't seem to take locale @@ -508,12 +508,12 @@ int ads_keytab_create_default(ADS_STRUCT *ads) } } } - krb5_kt_free_entry(context, &kt_entry); + krb5_free_keytab_entry_contents(context, &kt_entry); ZERO_STRUCT(kt_entry); } for (i = 0; oldEntries[i]; i++) { ret |= ads_keytab_add_entry(oldEntries[i], ads); - krb5_free_unparsed_name(oldEntries[i]); + krb5_free_unparsed_name(context, oldEntries[i]); } krb5_kt_end_seq_get(context, keytab, &cursor); } @@ -527,7 +527,7 @@ done: krb5_keytab_entry zero_kt_entry; ZERO_STRUCT(zero_kt_entry); if (memcmp(&zero_kt_entry, &kt_entry, sizeof(krb5_keytab_entry))) { - krb5_kt_free_entry(context, &kt_entry); + krb5_free_keytab_entry_contents(context, &kt_entry); } } if (cursor && keytab) { -- cgit From e948458a79462bd99ef7c02b4d7ec22c6554a163 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 22 Jun 2004 00:48:59 +0000 Subject: r1215: Intermediate checkin of the new keytab code. I need to make sure I haven't broken krb5 ticket verification in the mainline code path, also need to check with valgrind. Everything now compiles (MIT, need to also check Heimdal) and the "net keytab" utility code will follow. Jeremy. (This used to be commit f0f2e28958cb9abfed216c71f291f19ea346d630) --- source3/libads/kerberos_keytab.c | 30 +--- source3/libads/kerberos_verify.c | 297 +++++++++++++++++++++----------- source3/libads/ldap.c | 353 ++++++++++++++++++++++++++++++++------- 3 files changed, 498 insertions(+), 182 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c index dc25fb74c0..da504db363 100644 --- a/source3/libads/kerberos_keytab.c +++ b/source3/libads/kerberos_keytab.c @@ -29,27 +29,11 @@ #ifdef HAVE_KRB5 -/********************************************************************** - Converts a name to a fully qalified domain name. -***********************************************************************/ - -void name_to_fqdn(fstring fqdn, const char *name) -{ - struct hostent *hp = sys_gethostbyname(name); - if ( hp && hp->h_name && *hp->h_name ) { - DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name, hp->h_name)); - fstrcpy(fqdn,hp->h_name); - } else { - DEBUG(10,("name_to_fqdn: lookup for %s failed.\n", name)); - fstrcpy(fqdn, name); - } -} - /********************************************************************** Adds a single service principal, i.e. 'host' to the system keytab ***********************************************************************/ -int ads_keytab_add_entry(const char *srvPrinc, ADS_STRUCT *ads) +int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc) { krb5_error_code ret = 0; krb5_context context = NULL; @@ -254,8 +238,8 @@ int ads_keytab_add_entry(const char *srvPrinc, ADS_STRUCT *ads) /* Update the LDAP with the SPN */ DEBUG(3,("ads_keytab_add_entry: Attempting to add/update '%s'\n", princ_s)); - if (!ADS_ERR_OK(ads_add_spn(ads, global_myname(), srvPrinc))) { - DEBUG(1,("ads_keytab_add_entry: ads_add_spn failed.\n")); + if (!ADS_ERR_OK(ads_add_service_principal_name(ads, global_myname(), srvPrinc))) { + DEBUG(1,("ads_keytab_add_entry: ads_add_service_principcal_name failed.\n")); goto out; } @@ -372,7 +356,7 @@ int ads_keytab_flush(ADS_STRUCT *ads) ZERO_STRUCT(kt_entry); cursor = NULL; - if (!ADS_ERR_OK(ads_clear_spns(ads, global_myname()))) { + if (!ADS_ERR_OK(ads_clear_service_principal_names(ads, global_myname()))) { DEBUG(1,("ads_keytab_flush: Error while clearing service principal listings in LDAP.\n")); goto out; } @@ -413,12 +397,12 @@ int ads_keytab_create_default(ADS_STRUCT *ads) int i, found = 0; char **oldEntries = NULL; - ret = ads_keytab_add_entry("host", ads); + ret = ads_keytab_add_entry(ads, "host"); if (ret) { DEBUG(1,("ads_keytab_create_default: ads_keytab_add_entry failed while adding 'host'.\n")); return ret; } - ret = ads_keytab_add_entry("cifs", ads); + ret = ads_keytab_add_entry(ads, "cifs"); if (ret) { DEBUG(1,("ads_keytab_create_default: ads_keytab_add_entry failed while adding 'cifs'.\n")); return ret; @@ -512,7 +496,7 @@ int ads_keytab_create_default(ADS_STRUCT *ads) ZERO_STRUCT(kt_entry); } for (i = 0; oldEntries[i]; i++) { - ret |= ads_keytab_add_entry(oldEntries[i], ads); + ret |= ads_keytab_add_entry(ads, oldEntries[i]); krb5_free_unparsed_name(context, oldEntries[i]); } krb5_kt_end_seq_get(context, keytab, &cursor); diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 47559c1abb..2665f40c49 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -26,10 +26,166 @@ #ifdef HAVE_KRB5 -/* - verify an incoming ticket and parse out the principal name and - authorization_data if available -*/ +/********************************************************************************** + Try to verify a ticket using the system keytab... the system keytab has kvno -1 entries, so + it's more like what microsoft does... see comment in utils/net_ads.c in the + ads_keytab_add_entry function for details. +***********************************************************************************/ + +static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context auth_context, + const DATA_BLOB *ticket, krb5_data *p_packet, krb5_ticket **pp_tkt) +{ + krb5_error_code ret = 0; + BOOL auth_ok = False; + + krb5_keytab keytab = NULL; + krb5_kt_cursor cursor = NULL; + krb5_keytab_entry kt_entry; + char *princ_name = NULL; + + ZERO_STRUCT(kt_entry); + ret = krb5_kt_default(context, &keytab); + if (ret) { + DEBUG(1, ("ads_keytab_verify_ticket: krb5_kt_default failed (%s)\n", error_message(ret))); + goto out; + } + + ret = krb5_kt_start_seq_get(context, keytab, &cursor); + if (ret) { + DEBUG(1, ("ads_keytab_verify_ticket: krb5_kt_start_seq_get failed (%s)\n", error_message(ret))); + goto out; + } + + while (!krb5_kt_next_entry(context, keytab, &kt_entry, &cursor)) { + ret = krb5_unparse_name(context, kt_entry.principal, &princ_name); + if (ret) { + DEBUG(1, ("ads_keytab_verify_ticket: krb5_unparse_name failed (%s)\n", error_message(ret))); + goto out; + } + /* Look for a CIFS ticket */ + if (!StrnCaseCmp(princ_name, "cifs/", 5)) { + krb5_auth_con_setuseruserkey(context, auth_context, &kt_entry.key); + + p_packet->length = ticket->length; + p_packet->data = (krb5_pointer)ticket->data; + + if (!(ret = krb5_rd_req(context, &auth_context, p_packet, NULL, NULL, NULL, pp_tkt))) { + krb5_free_unparsed_name(context, princ_name); + princ_name = NULL; + DEBUG(10,("ads_keytab_verify_ticket: enc type [%u] decrypted message !\n", + (unsigned int) kt_entry.key.enctype)); + auth_ok = True; + break; + } + } + krb5_free_unparsed_name(context, princ_name); + princ_name = NULL; + } + if (ret && ret != KRB5_KT_END) { + /* This failed because something went wrong, not because the keytab file was empty. */ + DEBUG(1, ("ads_keytab_verify_ticket: krb5_kt_next_entry failed (%s)\n", error_message(ret))); + goto out; + } + + out: + + if (princ_name) { + krb5_free_unparsed_name(context, princ_name); + } + if (cursor && keytab) { + krb5_kt_end_seq_get(context, keytab, &cursor); + } + if (keytab) { + krb5_kt_close(context, keytab); + } + + return auth_ok; +} + +/********************************************************************************** + Try to verify a ticket using the secrets.tdb. +***********************************************************************************/ + +static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context auth_context, + krb5_principal host_princ, + const DATA_BLOB *ticket, krb5_data *p_packet, krb5_ticket **pp_tkt) +{ + krb5_error_code ret = 0; + BOOL auth_ok = False; + char *password_s = NULL; + krb5_data password; + krb5_enctype *enctypes = NULL; + int i; + + if (!secrets_init()) { + DEBUG(1,("ads_secrets_verify_ticket: secrets_init failed\n")); + return False; + } + + password_s = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL); + if (!password_s) { + DEBUG(1,("ads_secrets_verify_ticket: failed to fetch machine password\n")); + return False; + } + + password.data = password_s; + password.length = strlen(password_s); + + /* CIFS doesn't use addresses in tickets. This would break NAT. JRA */ + + if ((ret = get_kerberos_allowed_etypes(context, &enctypes))) { + DEBUG(1,("ads_secrets_verify_ticket: krb5_get_permitted_enctypes failed (%s)\n", + error_message(ret))); + goto out; + } + + p_packet->length = ticket->length; + p_packet->data = (krb5_pointer)ticket->data; + + /* We need to setup a auth context with each possible encoding type in turn. */ + for (i=0;enctypes[i];i++) { + krb5_keyblock *key = NULL; + + if (!(key = (krb5_keyblock *)malloc(sizeof(*key)))) { + goto out; + } + + if (create_kerberos_key_from_string(context, host_princ, &password, key, enctypes[i])) { + SAFE_FREE(key); + continue; + } + + krb5_auth_con_setuseruserkey(context, auth_context, key); + + krb5_free_keyblock(context, key); + + if (!(ret = krb5_rd_req(context, &auth_context, p_packet, + NULL, + NULL, NULL, pp_tkt))) { + DEBUG(10,("ads_secrets_verify_ticket: enc type [%u] decrypted message !\n", + (unsigned int)enctypes[i] )); + auth_ok = True; + break; + } + + DEBUG((ret != KRB5_BAD_ENCTYPE) ? 3 : 10, + ("ads_secrets_verify_ticket: enc type [%u] failed to decrypt with error %s\n", + (unsigned int)enctypes[i], error_message(ret))); + } + + out: + + free_kerberos_etypes(context, enctypes); + SAFE_FREE(password_s); + + return auth_ok; +} + +/********************************************************************************** + Verify an incoming ticket and parse out the principal name and + authorization_data if available. +***********************************************************************************/ + NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, char **principal, DATA_BLOB *auth_data, DATA_BLOB *ap_rep, @@ -41,43 +197,21 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, krb5_data packet; krb5_ticket *tkt = NULL; krb5_rcache rcache = NULL; - int ret, i; - krb5_keyblock *key = NULL; + int ret; - krb5_principal host_princ; + krb5_principal host_princ = NULL; char *host_princ_s = NULL; - BOOL free_host_princ = False; BOOL got_replay_mutex = False; fstring myname; - char *password_s = NULL; - krb5_data password; - krb5_enctype *enctypes = NULL; -#if 0 - krb5_address local_addr; - krb5_address remote_addr; -#endif BOOL auth_ok = False; ZERO_STRUCT(packet); - ZERO_STRUCT(password); ZERO_STRUCTP(auth_data); ZERO_STRUCTP(ap_rep); + ZERO_STRUCTP(session_key); - if (!secrets_init()) { - DEBUG(1,("ads_verify_ticket: secrets_init failed\n")); - return NT_STATUS_LOGON_FAILURE; - } - - password_s = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL); - if (!password_s) { - DEBUG(1,("ads_verify_ticket: failed to fetch machine password\n")); - return NT_STATUS_LOGON_FAILURE; - } - - password.data = password_s; - password.length = strlen(password_s); - + initialize_krb5_error_table(); ret = krb5_init_context(&context); if (ret) { DEBUG(1,("ads_verify_ticket: krb5_init_context failed (%s)\n", error_message(ret))); @@ -87,7 +221,6 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, ret = krb5_set_default_realm(context, realm); if (ret) { DEBUG(1,("ads_verify_ticket: krb5_set_default_realm failed (%s)\n", error_message(ret))); - sret = NT_STATUS_LOGON_FAILURE; goto out; } @@ -98,22 +231,29 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, ret = krb5_auth_con_init(context, &auth_context); if (ret) { DEBUG(1,("ads_verify_ticket: krb5_auth_con_init failed (%s)\n", error_message(ret))); - sret = NT_STATUS_LOGON_FAILURE; goto out; } - fstrcpy(myname, global_myname()); + name_to_fqdn(myname, global_myname()); strlower_m(myname); - asprintf(&host_princ_s, "HOST/%s@%s", myname, lp_realm()); + asprintf(&host_princ_s, "host/%s@%s", myname, lp_realm()); ret = krb5_parse_name(context, host_princ_s, &host_princ); if (ret) { DEBUG(1,("ads_verify_ticket: krb5_parse_name(%s) failed (%s)\n", host_princ_s, error_message(ret))); - sret = NT_STATUS_LOGON_FAILURE; goto out; } - free_host_princ = True; + + /* Lock a mutex surrounding the replay as there is no locking in the MIT krb5 + * code surrounding the replay cache... */ + + if (!grab_server_mutex("replay cache mutex")) { + DEBUG(1,("ads_verify_ticket: unable to protect replay cache with mutex.\n")); + goto out; + } + + got_replay_mutex = True; /* * JRA. We must set the rcache here. This will prevent replay attacks. @@ -122,67 +262,21 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, ret = krb5_get_server_rcache(context, krb5_princ_component(context, host_princ, 0), &rcache); if (ret) { DEBUG(1,("ads_verify_ticket: krb5_get_server_rcache failed (%s)\n", error_message(ret))); - sret = NT_STATUS_LOGON_FAILURE; goto out; } ret = krb5_auth_con_setrcache(context, auth_context, rcache); if (ret) { DEBUG(1,("ads_verify_ticket: krb5_auth_con_setrcache failed (%s)\n", error_message(ret))); - sret = NT_STATUS_LOGON_FAILURE; goto out; } - /* CIFS doesn't use addresses in tickets. This would breat NAT. JRA */ - - if ((ret = get_kerberos_allowed_etypes(context, &enctypes))) { - DEBUG(1,("ads_verify_ticket: krb5_get_permitted_enctypes failed (%s)\n", - error_message(ret))); - sret = NT_STATUS_LOGON_FAILURE; - goto out; - } - - /* Lock a mutex surrounding the replay as there is no locking in the MIT krb5 - * code surrounding the replay cache... */ - - if (!grab_server_mutex("replay cache mutex")) { - DEBUG(1,("ads_verify_ticket: unable to protect replay cache with mutex.\n")); - sret = NT_STATUS_LOGON_FAILURE; - goto out; + if (lp_use_kerberos_keytab()) { + auth_ok = ads_keytab_verify_ticket(context, auth_context, ticket, &packet, &tkt); } - - got_replay_mutex = True; - - /* We need to setup a auth context with each possible encoding type in turn. */ - for (i=0;enctypes[i];i++) { - if (!(key = (krb5_keyblock *)malloc(sizeof(*key)))) { - sret = NT_STATUS_NO_MEMORY; - goto out; - } - - if (create_kerberos_key_from_string(context, host_princ, &password, key, enctypes[i])) { - continue; - } - - krb5_auth_con_setuseruserkey(context, auth_context, key); - - krb5_free_keyblock(context, key); - - packet.length = ticket->length; - packet.data = (krb5_pointer)ticket->data; - - if (!(ret = krb5_rd_req(context, &auth_context, &packet, - NULL, - NULL, NULL, &tkt))) { - DEBUG(10,("ads_verify_ticket: enc type [%u] decrypted message !\n", - (unsigned int)enctypes[i] )); - auth_ok = True; - break; - } - - DEBUG((ret != KRB5_BAD_ENCTYPE) ? 3 : 10, - ("ads_verify_ticket: enc type [%u] failed to decrypt with error %s\n", - (unsigned int)enctypes[i], error_message(ret))); + if (!auth_ok) { + auth_ok = ads_secrets_verify_ticket(context, auth_context, host_princ, + ticket, &packet, &tkt); } release_server_mutex(); @@ -191,7 +285,6 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, if (!auth_ok) { DEBUG(3,("ads_verify_ticket: krb5_rd_req with auth failed (%s)\n", error_message(ret))); - sret = NT_STATUS_LOGON_FAILURE; goto out; } @@ -199,12 +292,12 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, if (ret) { DEBUG(3,("ads_verify_ticket: Failed to generate mutual authentication reply (%s)\n", error_message(ret))); - sret = NT_STATUS_LOGON_FAILURE; goto out; } *ap_rep = data_blob(packet.data, packet.length); - free(packet.data); + SAFE_FREE(packet.data); + packet.length = 0; get_krb5_smb_session_key(context, auth_context, session_key, True); dump_data_pw("SMB session key (from ticket)\n", session_key->data, session_key->length); @@ -241,29 +334,35 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, out: - if (got_replay_mutex) + if (got_replay_mutex) { release_server_mutex(); + } - if (!NT_STATUS_IS_OK(sret)) + if (!NT_STATUS_IS_OK(sret)) { data_blob_free(auth_data); + } - if (!NT_STATUS_IS_OK(sret)) + if (!NT_STATUS_IS_OK(sret)) { data_blob_free(ap_rep); + } - if (free_host_princ) + if (host_princ) { krb5_free_principal(context, host_princ); + } - if (tkt != NULL) + if (tkt != NULL) { krb5_free_ticket(context, tkt); - free_kerberos_etypes(context, enctypes); - SAFE_FREE(password_s); + } + SAFE_FREE(host_princ_s); - if (auth_context) + if (auth_context) { krb5_auth_con_free(context, auth_context); + } - if (context) + if (context) { krb5_free_context(context); + } return sret; } diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index e018eeb2da..3a9c41f09d 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -226,11 +226,10 @@ got_connection: ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); if (!ads->auth.user_name) { - /* by default use the machine account */ - fstring myname; - fstrcpy(myname, global_myname()); - strlower_m(myname); - asprintf(&ads->auth.user_name, "HOST/%s", myname); + fstring my_fqdn; + name_to_fqdn(my_fqdn, global_myname()); + strlower_m(my_fqdn); + asprintf(&ads->auth.user_name, "host/%s", my_fqdn); } if (!ads->auth.realm) { @@ -730,7 +729,7 @@ char *ads_get_dn(ADS_STRUCT *ads, void *msg) * @param host Hostname to search for * @return status of search **/ -ADS_STATUS ads_find_machine_acct(ADS_STRUCT *ads, void **res, const char *host) +ADS_STATUS ads_find_machine_acct(ADS_STRUCT *ads, void **res, const char *machine) { ADS_STATUS status; char *expr; @@ -738,13 +737,13 @@ ADS_STATUS ads_find_machine_acct(ADS_STRUCT *ads, void **res, const char *host) /* the easiest way to find a machine account anywhere in the tree is to look for hostname$ */ - if (asprintf(&expr, "(samAccountName=%s$)", host) == -1) { + if (asprintf(&expr, "(samAccountName=%s$)", machine) == -1) { DEBUG(1, ("asprintf failed!\n")); return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); } status = ads_search(ads, res, expr, attrs); - free(expr); + SAFE_FREE(expr); return status; } @@ -979,18 +978,231 @@ char *ads_ou_string(const char *org_unit) return ads_build_path(org_unit, "\\/", "ou=", 1); } +/** + * Adds (appends) an item to an attribute array, rather then + * replacing the whole list + * @param ctx An initialized TALLOC_CTX + * @param mods An initialized ADS_MODLIST + * @param name name of the ldap attribute to append to + * @param vals an array of values to add + * @return status of addition + **/ + +ADS_STATUS ads_add_strlist(TALLOC_CTX *ctx, ADS_MODLIST *mods, + const char *name, const char **vals) +{ + return ads_modlist_add(ctx, mods, LDAP_MOD_ADD, name, (const void **) vals); +} +/** + * Determines the computer account's current KVNO via an LDAP lookup + * @param ads An initialized ADS_STRUCT + * @param machine_name the NetBIOS name of the computer, which is used to identify the computer account. + * @return the kvno for the computer account, or -1 in case of a failure. + **/ -/* - add a machine account to the ADS server -*/ -static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, +uint32 ads_get_kvno(ADS_STRUCT *ads, const char *machine_name) +{ + LDAPMessage *res; + uint32 kvno = (uint32)-1; /* -1 indicates a failure */ + char *filter; + const char *attrs[] = {"msDS-KeyVersionNumber", NULL}; + char *dn_string = NULL; + ADS_STATUS ret = ADS_ERROR(LDAP_SUCCESS); + + DEBUG(5,("ads_get_kvno: Searching for host %s\n", machine_name)); + if (asprintf(&filter, "(samAccountName=%s$)", machine_name) == -1) { + return kvno; + } + ret = ads_search(ads, (void**) &res, filter, attrs); + SAFE_FREE(filter); + if (!ADS_ERR_OK(ret) && ads_count_replies(ads, res)) { + DEBUG(1,("ads_get_kvno: Computer Account For %s not found.\n", machine_name)); + return kvno; + } + + dn_string = ads_get_dn(ads, res); + if (!dn_string) { + DEBUG(0,("ads_get_kvno: out of memory.\n")); + return kvno; + } + DEBUG(5,("ads_get_kvno: Using: %s\n", dn_string)); + ads_memfree(ads, dn_string); + + /* --------------------------------------------------------- + * 0 is returned as a default KVNO from this point on... + * This is done because Windows 2000 does not support key + * version numbers. Chances are that a failure in the next + * step is simply due to Windows 2000 being used for a + * domain controller. */ + kvno = 0; + + if (!ads_pull_uint32(ads, res, "msDS-KeyVersionNumber", &kvno)) { + DEBUG(3,("ads_get_kvno: Error Determining KVNO!\n")); + DEBUG(3,("ads_get_kvno: Windows 2000 does not support KVNO's, so this may be normal.\n")); + return kvno; + } + + /* Success */ + DEBUG(5,("ads_get_kvno: Looked Up KVNO of: %d\n", kvno)); + return kvno; +} + +/** + * This clears out all registered spn's for a given hostname + * @param ads An initilaized ADS_STRUCT + * @param machine_name the NetBIOS name of the computer. + * @return 0 upon success, non-zero otherwise. + **/ + +ADS_STATUS ads_clear_service_principal_names(ADS_STRUCT *ads, const char *machine_name) +{ + TALLOC_CTX *ctx; + LDAPMessage *res; + ADS_MODLIST mods; + const char *servicePrincipalName[1] = {NULL}; + ADS_STATUS ret = ADS_ERROR(LDAP_SUCCESS); + char *dn_string = NULL; + + ret = ads_find_machine_acct(ads, (void **)&res, machine_name); + if (!ADS_ERR_OK(ret) || ads_count_replies(ads, res) != 1) { + DEBUG(5,("ads_clear_service_principal_names: WARNING: Host Account for %s not found... skipping operation.\n", machine_name)); + DEBUG(5,("ads_clear_service_principal_names: WARNING: Service Principals for %s have NOT been cleared.\n", machine_name)); + return ADS_ERROR(LDAP_NO_SUCH_OBJECT); + } + + DEBUG(5,("ads_clear_service_principal_names: Host account for %s found\n", machine_name)); + ctx = talloc_init("ads_clear_service_principal_names"); + if (!ctx) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + + if (!(mods = ads_init_mods(ctx))) { + talloc_destroy(ctx); + return ADS_ERROR(LDAP_NO_MEMORY); + } + ret = ads_mod_strlist(ctx, &mods, "servicePrincipalName", servicePrincipalName); + if (!ADS_ERR_OK(ret)) { + DEBUG(1,("ads_clear_service_principal_names: Error creating strlist.\n")); + talloc_destroy(ctx); + return ret; + } + dn_string = ads_get_dn(ads, res); + if (!dn_string) { + talloc_destroy(ctx); + return ADS_ERROR(LDAP_NO_MEMORY); + } + ret = ads_gen_mod(ads, dn_string, mods); + ads_memfree(ads,dn_string); + if (!ADS_ERR_OK(ret)) { + DEBUG(1,("ads_clear_service_principal_names: Error: Updating Service Principals for machine %s in LDAP\n", + machine_name)); + talloc_destroy(ctx); + return ret; + } + + talloc_destroy(ctx); + return ret; +} + +/** + * This adds a service principal name to an existing computer account + * (found by hostname) in AD. + * @param ads An initialized ADS_STRUCT + * @param machine_name the NetBIOS name of the computer, which is used to identify the computer account. + * @param spn A string of the service principal to add, i.e. 'host' + * @return 0 upon sucess, or non-zero if a failure occurs + **/ + +ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_name, const char *spn) +{ + ADS_STATUS ret; + TALLOC_CTX *ctx; + LDAPMessage *res; + char *host_spn, *host_upn, *psp1, *psp2; + ADS_MODLIST mods; + fstring my_fqdn; + char *dn_string = NULL; + const char *servicePrincipalName[3] = {NULL, NULL, NULL}; + + ret = ads_find_machine_acct(ads, (void **)&res, machine_name); + if (!ADS_ERR_OK(ret) || ads_count_replies(ads, res) != 1) { + DEBUG(1,("ads_add_service_principal_name: WARNING: Host Account for %s not found... skipping operation.\n", + machine_name)); + DEBUG(1,("ads_add_service_principal_name: WARNING: Service Principal '%s/%s@%s' has NOT been added.\n", + spn, machine_name, ads->config.realm)); + return ADS_ERROR(LDAP_NO_SUCH_OBJECT); + } + + DEBUG(1,("ads_add_service_principal_name: Host account for %s found\n", machine_name)); + if (!(ctx = talloc_init("ads_add_service_principal_name"))) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + + name_to_fqdn(my_fqdn, machine_name); + if (!(host_spn = talloc_asprintf(ctx, "HOST/%s", my_fqdn))) { + talloc_destroy(ctx); + return ADS_ERROR(LDAP_NO_SUCH_OBJECT); + } + if (!(host_upn = talloc_asprintf(ctx, "%s@%s", host_spn, ads->config.realm))) { + talloc_destroy(ctx); + return ADS_ERROR(LDAP_NO_SUCH_OBJECT); + } + + /* Add the extra principal */ + psp1 = talloc_asprintf(ctx, "%s/%s", spn, machine_name); + strupper_m(psp1); + strlower_m(&psp1[strlen(spn)]); + DEBUG(5,("ads_add_service_principal_name: INFO: Adding %s to host %s\n", psp1, machine_name)); + servicePrincipalName[0] = psp1; + psp2 = talloc_asprintf(ctx, "%s/%s.%s", spn, machine_name, ads->config.realm); + strupper_m(psp2); + strlower_m(&psp2[strlen(spn)]); + DEBUG(5,("ads_add_service_principal_name: INFO: Adding %s to host %s\n", psp2, machine_name)); + servicePrincipalName[1] = psp2; + + if (!(mods = ads_init_mods(ctx))) { + talloc_destroy(ctx); + return ADS_ERROR(LDAP_NO_MEMORY); + } + ret = ads_add_strlist(ctx, &mods, "servicePrincipalName", servicePrincipalName); + if (!ADS_ERR_OK(ret)) { + DEBUG(1,("ads_add_service_principal_name: Error: Updating Service Principals in LDAP\n")); + talloc_destroy(ctx); + return ret; + } + dn_string = ads_get_dn(ads, res); + if (!dn_string) { + talloc_destroy(ctx); + return ADS_ERROR(LDAP_NO_MEMORY); + } + ret = ads_gen_mod(ads, ads_get_dn(ads, res), mods); + ads_memfree(ads,dn_string); + if (!ADS_ERR_OK(ret)) { + DEBUG(1,("ads_add_service_principal_name: Error: Updating Service Principals in LDAP\n")); + talloc_destroy(ctx); + return ret; + } + + talloc_destroy(ctx); + return ret; +} + +/** + * adds a machine account to the ADS server + * @param ads An intialized ADS_STRUCT + * @param machine_name - the NetBIOS machine name of this account. + * @param account_type A number indicating the type of account to create + * @param org_unit The LDAP path in which to place this account + * @return 0 upon success, or non-zero otherwise +**/ + +static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *machine_name, uint32 account_type, const char *org_unit) { ADS_STATUS ret, status; char *host_spn, *host_upn, *new_dn, *samAccountName, *controlstr; - char *ou_str; TALLOC_CTX *ctx; ADS_MODLIST mods; const char *objectClass[] = {"top", "person", "organizationalPerson", @@ -999,87 +1211,106 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, char *psp, *psp2; unsigned acct_control; unsigned exists=0; + fstring my_fqdn; LDAPMessage *res; - status = ads_find_machine_acct(ads, (void **)&res, hostname); + if (!(ctx = talloc_init("ads_add_machine_acct"))) + return ADS_ERROR(LDAP_NO_MEMORY); + + ret = ADS_ERROR(LDAP_NO_MEMORY); + + name_to_fqdn(my_fqdn, machine_name); + + status = ads_find_machine_acct(ads, (void **)&res, machine_name); if (ADS_ERR_OK(status) && ads_count_replies(ads, res) == 1) { - DEBUG(0, ("Host account for %s already exists - modifying old account\n", hostname)); + char *dn_string = ads_get_dn(ads, res); + if (!dn_string) { + DEBUG(1, ("ads_add_machine_acct: ads_get_dn returned NULL (malloc failure?)\n")); + goto done; + } + new_dn = talloc_strdup(ctx, dn_string); + ads_memfree(ads,dn_string); + DEBUG(0, ("ads_add_machine_acct: Host account for %s already exists - modifying old account\n", + machine_name)); exists=1; - } + } else { + char *ou_str = ads_ou_string(org_unit); + if (!ou_str) { + DEBUG(1, ("ads_add_machine_acct: ads_ou_string returned NULL (malloc failure?)\n")); + goto done; + } + new_dn = talloc_asprintf(ctx, "cn=%s,%s,%s", machine_name, ou_str, + ads->config.bind_path); - if (!(ctx = talloc_init("machine_account"))) - return ADS_ERROR(LDAP_NO_MEMORY); + SAFE_FREE(ou_str); + } - ret = ADS_ERROR(LDAP_NO_MEMORY); + if (!new_dn) { + goto done; + } - if (!(host_spn = talloc_asprintf(ctx, "HOST/%s", hostname))) + if (!(host_spn = talloc_asprintf(ctx, "HOST/%s", machine_name))) goto done; if (!(host_upn = talloc_asprintf(ctx, "%s@%s", host_spn, ads->config.realm))) goto done; - ou_str = ads_ou_string(org_unit); - if (!ou_str) { - DEBUG(1, ("ads_ou_string returned NULL (malloc failure?)\n")); - goto done; - } - new_dn = talloc_asprintf(ctx, "cn=%s,%s,%s", hostname, ou_str, - ads->config.bind_path); - servicePrincipalName[0] = talloc_asprintf(ctx, "HOST/%s", hostname); + servicePrincipalName[0] = talloc_asprintf(ctx, "HOST/%s", machine_name); psp = talloc_asprintf(ctx, "HOST/%s.%s", - hostname, - ads->config.realm); + machine_name, + ads->config.realm); strlower_m(&psp[5]); servicePrincipalName[1] = psp; - servicePrincipalName[2] = talloc_asprintf(ctx, "CIFS/%s", hostname); + servicePrincipalName[2] = talloc_asprintf(ctx, "CIFS/%s", machine_name); psp2 = talloc_asprintf(ctx, "CIFS/%s.%s", - hostname, + machine_name, ads->config.realm); strlower_m(&psp2[5]); servicePrincipalName[3] = psp2; - free(ou_str); - if (!new_dn) - goto done; - - if (!(samAccountName = talloc_asprintf(ctx, "%s$", hostname))) + if (!(samAccountName = talloc_asprintf(ctx, "%s$", machine_name))) { goto done; + } acct_control = account_type | UF_DONT_EXPIRE_PASSWD; #ifndef ENCTYPE_ARCFOUR_HMAC acct_control |= UF_USE_DES_KEY_ONLY; #endif - if (!(controlstr = talloc_asprintf(ctx, "%u", acct_control))) + if (!(controlstr = talloc_asprintf(ctx, "%u", acct_control))) { goto done; + } - if (!(mods = ads_init_mods(ctx))) + if (!(mods = ads_init_mods(ctx))) { goto done; + } if (!exists) { - ads_mod_str(ctx, &mods, "cn", hostname); + ads_mod_str(ctx, &mods, "cn", machine_name); ads_mod_str(ctx, &mods, "sAMAccountName", samAccountName); ads_mod_str(ctx, &mods, "userAccountControl", controlstr); ads_mod_strlist(ctx, &mods, "objectClass", objectClass); } - ads_mod_str(ctx, &mods, "dNSHostName", hostname); + ads_mod_str(ctx, &mods, "dNSHostName", my_fqdn); ads_mod_str(ctx, &mods, "userPrincipalName", host_upn); ads_mod_strlist(ctx, &mods, "servicePrincipalName", servicePrincipalName); ads_mod_str(ctx, &mods, "operatingSystem", "Samba"); ads_mod_str(ctx, &mods, "operatingSystemVersion", SAMBA_VERSION_STRING); - if (!exists) + if (!exists) { ret = ads_gen_add(ads, new_dn, mods); - else + } else { ret = ads_gen_mod(ads, new_dn, mods); + } - if (!ADS_ERR_OK(ret)) + if (!ADS_ERR_OK(ret)) { goto done; + } /* Do not fail if we can't set security descriptor * it shouldn't be mandatory and probably we just * don't have enough rights to do it. */ if (!exists) { - status = ads_set_machine_sd(ads, hostname, new_dn); + status = ads_set_machine_sd(ads, machine_name, new_dn); if (!ADS_ERR_OK(status)) { DEBUG(0, ("Warning: ads_set_machine_sd: %s\n", @@ -1303,47 +1534,49 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) * Join a machine to a realm * Creates the machine account and sets the machine password * @param ads connection to ads server - * @param hostname name of host to add + * @param machine name of host to add * @param org_unit Organizational unit to place machine in * @return status of join **/ -ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *hostname, +ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *machine_name, uint32 account_type, const char *org_unit) { ADS_STATUS status; LDAPMessage *res; - char *host; + char *machine; - /* hostname must be lowercase */ - host = strdup(hostname); - strlower_m(host); + /* machine name must be lowercase */ + machine = strdup(machine_name); + strlower_m(machine); /* - status = ads_find_machine_acct(ads, (void **)&res, host); + status = ads_find_machine_acct(ads, (void **)&res, machine); if (ADS_ERR_OK(status) && ads_count_replies(ads, res) == 1) { - DEBUG(0, ("Host account for %s already exists - deleting old account\n", host)); - status = ads_leave_realm(ads, host); + DEBUG(0, ("Host account for %s already exists - deleting old account\n", machine)); + status = ads_leave_realm(ads, machine); if (!ADS_ERR_OK(status)) { DEBUG(0, ("Failed to delete host '%s' from the '%s' realm.\n", - host, ads->config.realm)); + machine, ads->config.realm)); return status; } } */ - status = ads_add_machine_acct(ads, host, account_type, org_unit); + status = ads_add_machine_acct(ads, machine, account_type, org_unit); if (!ADS_ERR_OK(status)) { - DEBUG(0, ("ads_add_machine_acct: %s\n", ads_errstr(status))); + DEBUG(0, ("ads_add_machine_acct (%s): %s\n", machine, ads_errstr(status))); + SAFE_FREE(machine); return status; } - status = ads_find_machine_acct(ads, (void **)&res, host); + status = ads_find_machine_acct(ads, (void **)&res, machine); if (!ADS_ERR_OK(status)) { - DEBUG(0, ("Host account test failed\n")); + DEBUG(0, ("Host account test failed for machine %s\n", machine)); + SAFE_FREE(machine); return status; } - free(host); + SAFE_FREE(machine); return status; } -- cgit From 20551552913e6794556ed86b2e912b773a74bd45 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 22 Jun 2004 21:58:35 +0000 Subject: r1221: Added the last of the system keytab patch from "Dan Perry" , fixed valgrind detected mem corruption in libads/kerberos_keytab.c. Jeremy. (This used to be commit 286f4c809cb1532b3f8ae7ddf92349c68cc8ce31) --- source3/libads/kerberos_keytab.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c index da504db363..410aad649c 100644 --- a/source3/libads/kerberos_keytab.c +++ b/source3/libads/kerberos_keytab.c @@ -225,7 +225,7 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc) DEBUG(3,("ads_keytab_add_entry: adding keytab entry for (%s) with encryption type (%d) and version (%d)\n", princ_s, enctypes[i], kt_entry.vno)); ret = krb5_kt_add_entry(context, keytab, &kt_entry); - krb5_free_keyblock(context, keyp); + krb5_free_keyblock_contents(context, keyp); ZERO_STRUCT(kt_entry); if (ret) { DEBUG(1,("ads_keytab_add_entry: adding entry to keytab failed (%s)\n", error_message(ret))); -- cgit From 7825677b862bb62b8350b6fee458fbbecc53893f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 23 Jun 2004 00:20:31 +0000 Subject: r1222: Valgrind memory leak fixes. Still tracking down a strange one... Can't fix the krb5 memory leaks inside that library :-(. Jeremy. (This used to be commit ad440213aaae58fb5bff6e8a6fcf811c5ba83669) --- source3/libads/kerberos_keytab.c | 4 ++++ source3/libads/krb5_setpw.c | 35 +++++++++++++++++++++++++---------- source3/libads/ldap.c | 34 ++++++++++++++++++++++++++++------ 3 files changed, 57 insertions(+), 16 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c index 410aad649c..cb0841f2e2 100644 --- a/source3/libads/kerberos_keytab.c +++ b/source3/libads/kerberos_keytab.c @@ -488,9 +488,13 @@ int ads_keytab_create_default(ADS_STRUCT *ads) break; } if (!strcmp(oldEntries[i], ktprinc)) { + krb5_free_unparsed_name(context, ktprinc); break; } } + if (i == found) { + krb5_free_unparsed_name(context, ktprinc); + } } krb5_free_keytab_entry_contents(context, &kt_entry); ZERO_STRUCT(kt_entry); diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 5c859f0e99..111834e886 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -56,7 +56,7 @@ static DATA_BLOB encode_krb5_setpw(const char *principal, const char *password) princ = strdup(principal); - if ((c = strchr(princ, '/')) == NULL) { + if ((c = strchr_m(princ, '/')) == NULL) { c = princ; } else { *c = '\0'; @@ -66,7 +66,7 @@ static DATA_BLOB encode_krb5_setpw(const char *principal, const char *password) princ_part2 = c; - if ((c = strchr(c, '@')) != NULL) { + if ((c = strchr_m(c, '@')) != NULL) { *c = '\0'; c++; realm = c; @@ -462,14 +462,16 @@ ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ, { ADS_STATUS aret; - krb5_error_code ret; + krb5_error_code ret = 0; krb5_context context = NULL; - krb5_principal principal; - char *princ_name; - char *realm; - krb5_creds creds, *credsp; + krb5_principal principal = NULL; + char *princ_name = NULL; + char *realm = NULL; + krb5_creds creds, *credsp = NULL; krb5_ccache ccache = NULL; + ZERO_STRUCT(creds); + ret = krb5_init_context(&context); if (ret) { DEBUG(1,("Failed to init krb5 context (%s)\n", error_message(ret))); @@ -487,14 +489,19 @@ ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ, return ADS_ERROR_KRB5(ret); } - ZERO_STRUCT(creds); - - realm = strchr(princ, '@'); + realm = strchr_m(princ, '@'); + if (!realm) { + krb5_cc_close(context, ccache); + krb5_free_context(context); + DEBUG(1,("Failed to get realm\n")); + return ADS_ERROR_KRB5(-1); + } realm++; asprintf(&princ_name, "kadmin/changepw@%s", realm); ret = krb5_parse_name(context, princ_name, &creds.server); if (ret) { + krb5_cc_close(context, ccache); krb5_free_context(context); DEBUG(1,("Failed to parse kadmin/changepw (%s)\n", error_message(ret))); return ADS_ERROR_KRB5(ret); @@ -504,6 +511,8 @@ ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ, /* parse the principal we got as a function argument */ ret = krb5_parse_name(context, princ, &principal); if (ret) { + krb5_cc_close(context, ccache); + krb5_free_principal(context, creds.server); krb5_free_context(context); DEBUG(1,("Failed to parse %s (%s)\n", princ_name, error_message(ret))); return ADS_ERROR_KRB5(ret); @@ -514,6 +523,8 @@ ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ, ret = krb5_cc_get_principal(context, ccache, &creds.client); if (ret) { + krb5_cc_close(context, ccache); + krb5_free_principal(context, creds.server); krb5_free_principal(context, principal); krb5_free_context(context); DEBUG(1,("Failed to get principal from ccache (%s)\n", @@ -523,7 +534,9 @@ ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ, ret = krb5_get_credentials(context, 0, ccache, &creds, &credsp); if (ret) { + krb5_cc_close(context, ccache); krb5_free_principal(context, creds.client); + krb5_free_principal(context, creds.server); krb5_free_principal(context, principal); krb5_free_context(context); DEBUG(1,("krb5_get_credentials failed (%s)\n", error_message(ret))); @@ -538,7 +551,9 @@ ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ, krb5_free_creds(context, credsp); krb5_free_principal(context, creds.client); + krb5_free_principal(context, creds.server); krb5_free_principal(context, principal); + krb5_cc_close(context, ccache); krb5_free_context(context); return aret; diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 3a9c41f09d..985d3cb576 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1003,7 +1003,7 @@ ADS_STATUS ads_add_strlist(TALLOC_CTX *ctx, ADS_MODLIST *mods, uint32 ads_get_kvno(ADS_STRUCT *ads, const char *machine_name) { - LDAPMessage *res; + LDAPMessage *res = NULL; uint32 kvno = (uint32)-1; /* -1 indicates a failure */ char *filter; const char *attrs[] = {"msDS-KeyVersionNumber", NULL}; @@ -1018,12 +1018,14 @@ uint32 ads_get_kvno(ADS_STRUCT *ads, const char *machine_name) SAFE_FREE(filter); if (!ADS_ERR_OK(ret) && ads_count_replies(ads, res)) { DEBUG(1,("ads_get_kvno: Computer Account For %s not found.\n", machine_name)); + ads_msgfree(ads, res); return kvno; } dn_string = ads_get_dn(ads, res); if (!dn_string) { DEBUG(0,("ads_get_kvno: out of memory.\n")); + ads_msgfree(ads, res); return kvno; } DEBUG(5,("ads_get_kvno: Using: %s\n", dn_string)); @@ -1040,11 +1042,13 @@ uint32 ads_get_kvno(ADS_STRUCT *ads, const char *machine_name) if (!ads_pull_uint32(ads, res, "msDS-KeyVersionNumber", &kvno)) { DEBUG(3,("ads_get_kvno: Error Determining KVNO!\n")); DEBUG(3,("ads_get_kvno: Windows 2000 does not support KVNO's, so this may be normal.\n")); + ads_msgfree(ads, res); return kvno; } /* Success */ DEBUG(5,("ads_get_kvno: Looked Up KVNO of: %d\n", kvno)); + ads_msgfree(ads, res); return kvno; } @@ -1058,7 +1062,7 @@ uint32 ads_get_kvno(ADS_STRUCT *ads, const char *machine_name) ADS_STATUS ads_clear_service_principal_names(ADS_STRUCT *ads, const char *machine_name) { TALLOC_CTX *ctx; - LDAPMessage *res; + LDAPMessage *res = NULL; ADS_MODLIST mods; const char *servicePrincipalName[1] = {NULL}; ADS_STATUS ret = ADS_ERROR(LDAP_SUCCESS); @@ -1068,28 +1072,33 @@ ADS_STATUS ads_clear_service_principal_names(ADS_STRUCT *ads, const char *machin if (!ADS_ERR_OK(ret) || ads_count_replies(ads, res) != 1) { DEBUG(5,("ads_clear_service_principal_names: WARNING: Host Account for %s not found... skipping operation.\n", machine_name)); DEBUG(5,("ads_clear_service_principal_names: WARNING: Service Principals for %s have NOT been cleared.\n", machine_name)); + ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_SUCH_OBJECT); } DEBUG(5,("ads_clear_service_principal_names: Host account for %s found\n", machine_name)); ctx = talloc_init("ads_clear_service_principal_names"); if (!ctx) { + ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_MEMORY); } if (!(mods = ads_init_mods(ctx))) { talloc_destroy(ctx); + ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_MEMORY); } ret = ads_mod_strlist(ctx, &mods, "servicePrincipalName", servicePrincipalName); if (!ADS_ERR_OK(ret)) { DEBUG(1,("ads_clear_service_principal_names: Error creating strlist.\n")); + ads_msgfree(ads, res); talloc_destroy(ctx); return ret; } dn_string = ads_get_dn(ads, res); if (!dn_string) { talloc_destroy(ctx); + ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_MEMORY); } ret = ads_gen_mod(ads, dn_string, mods); @@ -1097,10 +1106,12 @@ ADS_STATUS ads_clear_service_principal_names(ADS_STRUCT *ads, const char *machin if (!ADS_ERR_OK(ret)) { DEBUG(1,("ads_clear_service_principal_names: Error: Updating Service Principals for machine %s in LDAP\n", machine_name)); + ads_msgfree(ads, res); talloc_destroy(ctx); return ret; } + ads_msgfree(ads, res); talloc_destroy(ctx); return ret; } @@ -1118,7 +1129,7 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n { ADS_STATUS ret; TALLOC_CTX *ctx; - LDAPMessage *res; + LDAPMessage *res = NULL; char *host_spn, *host_upn, *psp1, *psp2; ADS_MODLIST mods; fstring my_fqdn; @@ -1131,21 +1142,25 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n machine_name)); DEBUG(1,("ads_add_service_principal_name: WARNING: Service Principal '%s/%s@%s' has NOT been added.\n", spn, machine_name, ads->config.realm)); + ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_SUCH_OBJECT); } DEBUG(1,("ads_add_service_principal_name: Host account for %s found\n", machine_name)); if (!(ctx = talloc_init("ads_add_service_principal_name"))) { + ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_MEMORY); } name_to_fqdn(my_fqdn, machine_name); if (!(host_spn = talloc_asprintf(ctx, "HOST/%s", my_fqdn))) { talloc_destroy(ctx); + ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_SUCH_OBJECT); } if (!(host_upn = talloc_asprintf(ctx, "%s@%s", host_spn, ads->config.realm))) { talloc_destroy(ctx); + ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_SUCH_OBJECT); } @@ -1163,28 +1178,33 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n if (!(mods = ads_init_mods(ctx))) { talloc_destroy(ctx); + ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_MEMORY); } ret = ads_add_strlist(ctx, &mods, "servicePrincipalName", servicePrincipalName); if (!ADS_ERR_OK(ret)) { DEBUG(1,("ads_add_service_principal_name: Error: Updating Service Principals in LDAP\n")); talloc_destroy(ctx); + ads_msgfree(ads, res); return ret; } dn_string = ads_get_dn(ads, res); if (!dn_string) { talloc_destroy(ctx); + ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_MEMORY); } - ret = ads_gen_mod(ads, ads_get_dn(ads, res), mods); + ret = ads_gen_mod(ads, dn_string, mods); ads_memfree(ads,dn_string); if (!ADS_ERR_OK(ret)) { DEBUG(1,("ads_add_service_principal_name: Error: Updating Service Principals in LDAP\n")); talloc_destroy(ctx); + ads_msgfree(ads, res); return ret; } talloc_destroy(ctx); + ads_msgfree(ads, res); return ret; } @@ -1212,7 +1232,7 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *machine_name unsigned acct_control; unsigned exists=0; fstring my_fqdn; - LDAPMessage *res; + LDAPMessage *res = NULL; if (!(ctx = talloc_init("ads_add_machine_acct"))) return ADS_ERROR(LDAP_NO_MEMORY); @@ -1318,6 +1338,7 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *machine_name } } done: + ads_msgfree(ads, res); talloc_destroy(ctx); return ret; } @@ -1542,7 +1563,7 @@ ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *machine_name, uint32 account_type, const char *org_unit) { ADS_STATUS status; - LDAPMessage *res; + LDAPMessage *res = NULL; char *machine; /* machine name must be lowercase */ @@ -1577,6 +1598,7 @@ ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *machine_name, } SAFE_FREE(machine); + ads_msgfree(ads, res); return status; } -- cgit From 1f7dbded0435f4f6b3e141edb89025542b904a57 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 23 Jun 2004 00:35:29 +0000 Subject: r1223: Fix valgrind error with realm manipulation.... Damn macros :-(. Jeremy. (This used to be commit 5a1d8c3c9b8daa435f6eb5bc1652bab138e05dbf) --- source3/libads/krb5_setpw.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 111834e886..c7e9e3fe76 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -468,6 +468,7 @@ ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ, char *princ_name = NULL; char *realm = NULL; krb5_creds creds, *credsp = NULL; + krb5_data orig_realm; krb5_ccache ccache = NULL; ZERO_STRUCT(creds); @@ -518,12 +519,15 @@ ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ, return ADS_ERROR_KRB5(ret); } - krb5_princ_set_realm(context, creds.server, - krb5_princ_realm(context, principal)); + /* The creds.server principal takes ownership of this memory. + Remember to set back to original value before freeing. */ + orig_realm = *krb5_princ_realm(context, creds.server); + krb5_princ_set_realm(context, creds.server, krb5_princ_realm(context, principal)); ret = krb5_cc_get_principal(context, ccache, &creds.client); if (ret) { krb5_cc_close(context, ccache); + krb5_princ_set_realm(context, creds.server, &orig_realm); krb5_free_principal(context, creds.server); krb5_free_principal(context, principal); krb5_free_context(context); @@ -536,6 +540,7 @@ ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ, if (ret) { krb5_cc_close(context, ccache); krb5_free_principal(context, creds.client); + krb5_princ_set_realm(context, creds.server, &orig_realm); krb5_free_principal(context, creds.server); krb5_free_principal(context, principal); krb5_free_context(context); @@ -551,6 +556,7 @@ ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ, krb5_free_creds(context, credsp); krb5_free_principal(context, creds.client); + krb5_princ_set_realm(context, creds.server, &orig_realm); krb5_free_principal(context, creds.server); krb5_free_principal(context, principal); krb5_cc_close(context, ccache); -- cgit From 2b76b28932d9d1ed714e79579414f630966342e7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 24 Jun 2004 05:56:44 +0000 Subject: r1236: Heimdal fixes from Guenther Deschner , more to come before it compiles with Heimdal. Jeremy. (This used to be commit dd07278b892770ac51750b87a4ab902d4de3a960) --- source3/libads/kerberos_keytab.c | 21 ++++++++++++--------- source3/libads/kerberos_verify.c | 8 ++++++++ 2 files changed, 20 insertions(+), 9 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c index cb0841f2e2..f312d8b8ef 100644 --- a/source3/libads/kerberos_keytab.c +++ b/source3/libads/kerberos_keytab.c @@ -48,6 +48,9 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc) char *principal = NULL; char *princ_s = NULL; char *password_s = NULL; +#ifndef MAX_KEYTAB_NAME_LEN +#define MAX_KEYTAB_NAME_LEN 1100 +#endif char keytab_name[MAX_KEYTAB_NAME_LEN]; /* This MAX_NAME_LEN is a constant defined in krb5.h */ fstring my_fqdn; int i; @@ -163,7 +166,7 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc) error_message(ret))); goto out; } - ret = krb5_free_keytab_entry_contents(context, &kt_entry); + ret = smb_krb5_kt_free_entry(context, &kt_entry); ZERO_STRUCT(kt_entry); if (ret) { DEBUG(1,("ads_keytab_add_entry: krb5_kt_remove_entry failed (%s)\n", @@ -174,10 +177,10 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc) } /* Not a match, just free this entry and continue. */ - ret = krb5_free_keytab_entry_contents(context, &kt_entry); + ret = smb_krb5_kt_free_entry(context, &kt_entry); ZERO_STRUCT(kt_entry); if (ret) { - DEBUG(1,("ads_keytab_add_entry: krb5_free_keytab_entry_contents failed (%s)\n", error_message(ret))); + DEBUG(1,("ads_keytab_add_entry: smb_krb5_kt_free_entry failed (%s)\n", error_message(ret))); goto out; } } @@ -253,7 +256,7 @@ out: krb5_keytab_entry zero_kt_entry; ZERO_STRUCT(zero_kt_entry); if (memcmp(&zero_kt_entry, &kt_entry, sizeof(krb5_keytab_entry))) { - krb5_free_keytab_entry_contents(context, &kt_entry); + smb_krb5_kt_free_entry(context, &kt_entry); } } if (princ) { @@ -343,7 +346,7 @@ int ads_keytab_flush(ADS_STRUCT *ads) DEBUG(1,("ads_keytab_flush: krb5_kt_start_seq failed (%s)\n",error_message(ret))); goto out; } - ret = krb5_free_keytab_entry_contents(context, &kt_entry); + ret = smb_krb5_kt_free_entry(context, &kt_entry); ZERO_STRUCT(kt_entry); if (ret) { DEBUG(1,("ads_keytab_flush: krb5_kt_remove_entry failed (%s)\n",error_message(ret))); @@ -367,7 +370,7 @@ out: krb5_keytab_entry zero_kt_entry; ZERO_STRUCT(zero_kt_entry); if (memcmp(&zero_kt_entry, &kt_entry, sizeof(krb5_keytab_entry))) { - krb5_free_keytab_entry_contents(context, &kt_entry); + smb_krb5_kt_free_entry(context, &kt_entry); } } if (cursor && keytab) { @@ -434,7 +437,7 @@ int ads_keytab_create_default(ADS_STRUCT *ads) ret = krb5_kt_start_seq_get(context, keytab, &cursor); if (ret != KRB5_KT_END && ret != ENOENT ) { while ((ret = krb5_kt_next_entry(context, keytab, &kt_entry, &cursor)) == 0) { - krb5_free_keytab_entry_contents(context, &kt_entry); + smb_krb5_kt_free_entry(context, &kt_entry); ZERO_STRUCT(kt_entry); found++; } @@ -496,7 +499,7 @@ int ads_keytab_create_default(ADS_STRUCT *ads) krb5_free_unparsed_name(context, ktprinc); } } - krb5_free_keytab_entry_contents(context, &kt_entry); + smb_krb5_kt_free_entry(context, &kt_entry); ZERO_STRUCT(kt_entry); } for (i = 0; oldEntries[i]; i++) { @@ -515,7 +518,7 @@ done: krb5_keytab_entry zero_kt_entry; ZERO_STRUCT(zero_kt_entry); if (memcmp(&zero_kt_entry, &kt_entry, sizeof(krb5_keytab_entry))) { - krb5_free_keytab_entry_contents(context, &kt_entry); + smb_krb5_kt_free_entry(context, &kt_entry); } } if (cursor && keytab) { diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 2665f40c49..8a18976b3a 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -64,7 +64,11 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut } /* Look for a CIFS ticket */ if (!StrnCaseCmp(princ_name, "cifs/", 5)) { +#ifdef HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK + krb5_auth_con_setuseruserkey(context, auth_context, &kt_entry.keyblock); +#else krb5_auth_con_setuseruserkey(context, auth_context, &kt_entry.key); +#endif p_packet->length = ticket->length; p_packet->data = (krb5_pointer)ticket->data; @@ -73,7 +77,11 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut krb5_free_unparsed_name(context, princ_name); princ_name = NULL; DEBUG(10,("ads_keytab_verify_ticket: enc type [%u] decrypted message !\n", +#ifdef HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK + (unsigned int) kt_entry.keyblock.keytype)); +#else (unsigned int) kt_entry.key.enctype)); +#endif auth_ok = True; break; } -- cgit From 34f985c971fa6b66db80793f00c0b16d16294d02 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 24 Jun 2004 19:48:52 +0000 Subject: r1243: Fix so this compiles with Heimdal (in Heimdal krb5_kt_cursor is a struct not a pointer). Jeremy. (This used to be commit 940f893d485a01e73afe714a70d724c2d41c7ad4) --- source3/libads/kerberos_keytab.c | 50 +++++++++++++++++++++++++++------------- 1 file changed, 34 insertions(+), 16 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c index f312d8b8ef..95152016b8 100644 --- a/source3/libads/kerberos_keytab.c +++ b/source3/libads/kerberos_keytab.c @@ -38,7 +38,7 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc) krb5_error_code ret = 0; krb5_context context = NULL; krb5_keytab keytab = NULL; - krb5_kt_cursor cursor = NULL; + krb5_kt_cursor cursor; krb5_keytab_entry kt_entry; krb5_principal princ = NULL; krb5_data password; @@ -57,6 +57,8 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc) char *ktprinc = NULL; ZERO_STRUCT(kt_entry); + ZERO_STRUCT(cursor); + initialize_krb5_error_table(); ret = krb5_init_context(&context); if (ret) { @@ -148,7 +150,7 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc) DEBUG(3,("ads_keytab_add_entry: Found old entry for principal: %s (kvno %d) - trying to remove it.\n", princ_s, kt_entry.vno)); ret = krb5_kt_end_seq_get(context, keytab, &cursor); - cursor = NULL; + ZERO_STRUCT(cursor); if (ret) { DEBUG(1,("ads_keytab_add_entry: krb5_kt_end_seq_get() failed (%s)\n", error_message(ret))); @@ -186,7 +188,7 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc) } ret = krb5_kt_end_seq_get(context, keytab, &cursor); - cursor = NULL; + ZERO_STRUCT(cursor); if (ret) { DEBUG(1,("ads_keytab_add_entry: krb5_kt_end_seq_get failed (%s)\n",error_message(ret))); goto out; @@ -195,7 +197,7 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc) /* Ensure we don't double free. */ ZERO_STRUCT(kt_entry); - cursor = NULL; + ZERO_STRUCT(cursor); /* If we get here, we have deleted all the old entries with kvno's not equal to the current kvno-1. */ @@ -265,8 +267,13 @@ out: if (enctypes) { free_kerberos_etypes(context, enctypes); } - if (cursor && keytab) { - krb5_kt_end_seq_get(context, keytab, &cursor); + + { + krb5_kt_cursor zero_csr; + ZERO_STRUCT(zero_csr); + if ((memcmp(&cursor, &zero_csr, sizeof(krb5_kt_cursor)) != 0) && keytab) { + krb5_kt_end_seq_get(context, keytab, &cursor); + } } if (keytab) { krb5_kt_close(context, keytab); @@ -286,12 +293,14 @@ int ads_keytab_flush(ADS_STRUCT *ads) krb5_error_code ret = 0; krb5_context context = NULL; krb5_keytab keytab = NULL; - krb5_kt_cursor cursor = NULL; + krb5_kt_cursor cursor; krb5_keytab_entry kt_entry; krb5_kvno kvno; char keytab_name[MAX_KEYTAB_NAME_LEN]; ZERO_STRUCT(kt_entry); + ZERO_STRUCT(cursor); + initialize_krb5_error_table(); ret = krb5_init_context(&context); if (ret) { @@ -331,7 +340,7 @@ int ads_keytab_flush(ADS_STRUCT *ads) if (ret != KRB5_KT_END && ret != ENOENT) { while (!krb5_kt_next_entry(context, keytab, &kt_entry, &cursor)) { ret = krb5_kt_end_seq_get(context, keytab, &cursor); - cursor = NULL; + ZERO_STRUCT(cursor); if (ret) { DEBUG(1,("ads_keytab_flush: krb5_kt_end_seq_get() failed (%s)\n",error_message(ret))); goto out; @@ -357,7 +366,7 @@ int ads_keytab_flush(ADS_STRUCT *ads) /* Ensure we don't double free. */ ZERO_STRUCT(kt_entry); - cursor = NULL; + ZERO_STRUCT(cursor); if (!ADS_ERR_OK(ads_clear_service_principal_names(ads, global_myname()))) { DEBUG(1,("ads_keytab_flush: Error while clearing service principal listings in LDAP.\n")); @@ -373,8 +382,12 @@ out: smb_krb5_kt_free_entry(context, &kt_entry); } } - if (cursor && keytab) { - krb5_kt_end_seq_get(context, keytab, &cursor); + { + krb5_kt_cursor zero_csr; + ZERO_STRUCT(zero_csr); + if ((memcmp(&cursor, &zero_csr, sizeof(krb5_kt_cursor)) != 0) && keytab) { + krb5_kt_end_seq_get(context, keytab, &cursor); + } } if (keytab) { krb5_kt_close(context, keytab); @@ -394,7 +407,7 @@ int ads_keytab_create_default(ADS_STRUCT *ads) krb5_error_code ret = 0; krb5_context context = NULL; krb5_keytab keytab = NULL; - krb5_kt_cursor cursor = NULL; + krb5_kt_cursor cursor; krb5_keytab_entry kt_entry; krb5_kvno kvno; int i, found = 0; @@ -421,6 +434,7 @@ int ads_keytab_create_default(ADS_STRUCT *ads) /* Now loop through the keytab and update any other existing entries... */ ZERO_STRUCT(kt_entry); + ZERO_STRUCT(cursor); initialize_krb5_error_table(); ret = krb5_init_context(&context); @@ -443,7 +457,7 @@ int ads_keytab_create_default(ADS_STRUCT *ads) } } krb5_kt_end_seq_get(context, keytab, &cursor); - cursor = NULL; + ZERO_STRUCT(cursor); /* * Hmmm. There is no "rewind" function for the keytab. This means we have a race condition @@ -508,7 +522,7 @@ int ads_keytab_create_default(ADS_STRUCT *ads) } krb5_kt_end_seq_get(context, keytab, &cursor); } - cursor = NULL; + ZERO_STRUCT(cursor); done: @@ -521,8 +535,12 @@ done: smb_krb5_kt_free_entry(context, &kt_entry); } } - if (cursor && keytab) { - krb5_kt_end_seq_get(context, keytab, &cursor); + { + krb5_kt_cursor zero_csr; + ZERO_STRUCT(zero_csr); + if ((memcmp(&cursor, &zero_csr, sizeof(krb5_kt_cursor)) != 0) && keytab) { + krb5_kt_end_seq_get(context, keytab, &cursor); + } } if (keytab) { krb5_kt_close(context, keytab); -- cgit From c3f09f2347e5397ff4eea3fedf1d9cf3284f0162 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 24 Jun 2004 20:37:23 +0000 Subject: r1244: More Heimdal compile fixes. Jeremy. (This used to be commit 92a5dc1880a4fe0f3c3b56fc0958dbac77506b4f) --- source3/libads/kerberos_verify.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 8a18976b3a..d81a0a1629 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -39,11 +39,13 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut BOOL auth_ok = False; krb5_keytab keytab = NULL; - krb5_kt_cursor cursor = NULL; + krb5_kt_cursor cursor; krb5_keytab_entry kt_entry; char *princ_name = NULL; ZERO_STRUCT(kt_entry); + ZERO_STRUCT(cursor); + ret = krb5_kt_default(context, &keytab); if (ret) { DEBUG(1, ("ads_keytab_verify_ticket: krb5_kt_default failed (%s)\n", error_message(ret))); @@ -100,8 +102,12 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut if (princ_name) { krb5_free_unparsed_name(context, princ_name); } - if (cursor && keytab) { - krb5_kt_end_seq_get(context, keytab, &cursor); + { + krb5_kt_cursor zero_csr; + ZERO_STRUCT(zero_csr); + if ((memcmp(&cursor, &zero_csr, sizeof(krb5_kt_cursor)) != 0) && keytab) { + krb5_kt_end_seq_get(context, keytab, &cursor); + } } if (keytab) { krb5_kt_close(context, keytab); -- cgit From 41416f3876da5a43077ff991817e73c44dd6ae70 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 24 Jun 2004 20:37:54 +0000 Subject: r1245: I think the parameter for "password" and "data" was reversed. CHECK THIS ! Jeremy. (This used to be commit d4abeefe3e307ff226fba481ca2c743cde153e4b) --- source3/libads/kerberos.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index e8bf4b0846..97b895a241 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -79,9 +79,9 @@ int kerberos_kinit_password(const char *principal, const char *password, int tim return code; } - if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, NULL, + if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, password, kerb_prompter, - password, 0, NULL, NULL))) { + NULL, 0, NULL, NULL))) { krb5_free_principal(ctx, me); krb5_free_context(ctx); return code; -- cgit From 6106de34e56cf6a3b4655f799c88ab1c349ae4a9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 24 Jun 2004 21:35:16 +0000 Subject: r1247: Final fix to make this compile on Heimdal. Jeremy. (This used to be commit b462b8fa2f264bef62ed4cd2aaacb2f21e135068) --- source3/libads/krb5_setpw.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index c7e9e3fe76..84595212e6 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -468,7 +468,11 @@ ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ, char *princ_name = NULL; char *realm = NULL; krb5_creds creds, *credsp = NULL; +#if KRB5_PRINC_REALM_RETURNS_REALM + krb5_realm orig_realm; +#else krb5_data orig_realm; +#endif krb5_ccache ccache = NULL; ZERO_STRUCT(creds); -- cgit From dd8b8286d05ba9423f44bf3eda7bbf53f0528538 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 28 Jun 2004 10:01:20 +0000 Subject: r1282: gcc 3.2 on SuSE 8.2 does not like #ifdefs inside a macro argument (DEBUG). Volker (This used to be commit b491e76625f0d20fa9db2a3dbb22adc34ca7d414) --- source3/libads/kerberos_verify.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index d81a0a1629..f72c298399 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -78,12 +78,14 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut if (!(ret = krb5_rd_req(context, &auth_context, p_packet, NULL, NULL, NULL, pp_tkt))) { krb5_free_unparsed_name(context, princ_name); princ_name = NULL; - DEBUG(10,("ads_keytab_verify_ticket: enc type [%u] decrypted message !\n", + unsigned int keytype; #ifdef HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK - (unsigned int) kt_entry.keyblock.keytype)); + keytype = (unsigned int) kt_entry.keyblock.keytype; #else - (unsigned int) kt_entry.key.enctype)); + keytype = (unsigned int) kt_entry.key.enctype; #endif + DEBUG(10,("ads_keytab_verify_ticket: enc type [%u] decrypted message !\n", + keytype)); auth_ok = True; break; } -- cgit From 407ab8474a363ba03dcdda94fdeb17266e220e13 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 28 Jun 2004 10:23:49 +0000 Subject: r1285: Put variable definitions into a block before the statements... Volker (This used to be commit e8786506b86f129ba6401c09b89a26bfb335440e) --- source3/libads/kerberos_verify.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index f72c298399..bdac22a902 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -76,9 +76,9 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut p_packet->data = (krb5_pointer)ticket->data; if (!(ret = krb5_rd_req(context, &auth_context, p_packet, NULL, NULL, NULL, pp_tkt))) { + unsigned int keytype; krb5_free_unparsed_name(context, princ_name); princ_name = NULL; - unsigned int keytype; #ifdef HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK keytype = (unsigned int) kt_entry.keyblock.keytype; #else -- cgit From 569177a194ef990b55d3ad5d5243ca0f2659f25c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 1 Jul 2004 16:35:43 +0000 Subject: r1317: Patch from Joe Meadows "Joe Meadows" to add a timeout to the ldap open calls. New parameter, ldap timeout added. Jeremy. (This used to be commit e5b3094c4cc75eb07f667dd1aeb73921ed7366ac) --- source3/libads/ldap.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 985d3cb576..05d68e6ae6 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -37,6 +37,35 @@ * codepoints in UTF-8). This may have to change at some point **/ +static SIG_ATOMIC_T gotalarm; + +/*************************************************************** + Signal function to tell us we timed out. +****************************************************************/ + +static void gotalarm_sig(void) +{ + gotalarm = 1; +} + +LDAP *ldap_open_with_timeout(const char *server, int port, unsigned int to) +{ + LDAP *ldp = NULL; + + /* Setup timeout */ + gotalarm = 0; + CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig); + alarm(to); + /* End setup timeout. */ + + ldp = ldap_open(server, port); + + /* Teardown timeout. */ + CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN); + alarm(0); + + return ldp; +} /* try a connection to a given ldap server, returning True and setting the servers IP @@ -58,7 +87,7 @@ static BOOL ads_try_connect(ADS_STRUCT *ads, const char *server, unsigned port) /* this copes with inet_ntoa brokenness */ srv = strdup(server); - ads->ld = ldap_open(srv, port); + ads->ld = ldap_open_with_timeout(srv, port, lp_ldap_timeout()); if (!ads->ld) { free(srv); return False; -- cgit From 6c1baa6f4ccbbbd27b8972e49d9ec448f0ad83ba Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 3 Jul 2004 11:25:44 +0000 Subject: r1330: Fix the build for systems without ldap headers (This used to be commit b7267121af45d7173c310299bb52ae031ae1d501) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 05d68e6ae6..6b9792ec4c 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -48,7 +48,7 @@ static void gotalarm_sig(void) gotalarm = 1; } -LDAP *ldap_open_with_timeout(const char *server, int port, unsigned int to) + LDAP *ldap_open_with_timeout(const char *server, int port, unsigned int to) { LDAP *ldp = NULL; -- cgit From 12b0bd2aca1600a3b6e42b5a9d0a9ac0018c8444 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 6 Jul 2004 23:42:58 +0000 Subject: r1373: Fix from Guenther Deschner to ensure last error return is not invalid. Jeremy. (This used to be commit 4bdf914cba2a63d186138d1341a7260ad79da1f5) --- source3/libads/kerberos_keytab.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c index 95152016b8..eec5f104fd 100644 --- a/source3/libads/kerberos_keytab.c +++ b/source3/libads/kerberos_keytab.c @@ -479,7 +479,7 @@ int ads_keytab_create_default(ADS_STRUCT *ads) ret = krb5_kt_start_seq_get(context, keytab, &cursor); if (ret != KRB5_KT_END && ret != ENOENT ) { - while ((ret = krb5_kt_next_entry(context, keytab, &kt_entry, &cursor)) == 0) { + while (krb5_kt_next_entry(context, keytab, &kt_entry, &cursor) == 0) { if (kt_entry.vno != kvno) { char *ktprinc = NULL; char *p; @@ -516,6 +516,7 @@ int ads_keytab_create_default(ADS_STRUCT *ads) smb_krb5_kt_free_entry(context, &kt_entry); ZERO_STRUCT(kt_entry); } + ret = 0; for (i = 0; oldEntries[i]; i++) { ret |= ads_keytab_add_entry(ads, oldEntries[i]); krb5_free_unparsed_name(context, oldEntries[i]); -- cgit From bd1fbdbd8a9d5a0cfd9789852caa7eef335767ed Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 7 Jul 2004 18:12:09 +0000 Subject: r1378: Better debugging so I don't get confused what principal we mean. Jeremy. (This used to be commit de80e8b1698d34637cf9c105a8fe02f435d83b02) --- source3/libads/sasl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 18cbb46588..8eb2c86bed 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -201,14 +201,14 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) /* make sure the server understands kerberos */ for (i=0;OIDs[i];i++) { - DEBUG(3,("got OID=%s\n", OIDs[i])); + DEBUG(3,("ads_sasl_spnego_bind: got OID=%s\n", OIDs[i])); if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 || strcmp(OIDs[i], OID_KERBEROS5) == 0) { got_kerberos_mechanism = True; } free(OIDs[i]); } - DEBUG(3,("got principal=%s\n", principal)); + DEBUG(3,("ads_sasl_spnego_bind: got server principal name =%s\n", principal)); #ifdef HAVE_KRB5 if (!(ads->auth.flags & ADS_AUTH_DISABLE_KERBEROS) && -- cgit From 02001dfb6c3ffe3091001aeaa17e3d0b48933cfd Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 7 Jul 2004 18:15:24 +0000 Subject: r1381: fixing behavior found by gd@sernet.de; we must use the userPrincipalName value (host/hostname@REALM) and not the servicePrincipalName (host/fqdn@REALM) in the SASL binds (This used to be commit 959da6e176da9f6a687265e50489b7db3d6712c0) --- source3/libads/ldap.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 6b9792ec4c..78ea9f1497 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -255,10 +255,10 @@ got_connection: ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); if (!ads->auth.user_name) { - fstring my_fqdn; - name_to_fqdn(my_fqdn, global_myname()); - strlower_m(my_fqdn); - asprintf(&ads->auth.user_name, "host/%s", my_fqdn); + /* have to use the userPrincipalName value here and + not servicePrincipalName; found by Guenther Deschner @ Sernet */ + + asprintf(&ads->auth.user_name, "host/%s", global_myname() ); } if (!ads->auth.realm) { -- cgit From a817cc16b246d4f0cfd335884eec7380966c77a8 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 12 Aug 2004 20:27:09 +0000 Subject: r1789: compiler warnings from SuSE (This used to be commit 7e44193be103fad273796218c8f5e5f9a1657c3c) --- source3/libads/kerberos_verify.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index bdac22a902..961b92ccc6 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -26,6 +26,10 @@ #ifdef HAVE_KRB5 +#if !defined(HAVE_KRB5_PRINC_COMPONENT) +const krb5_data *krb5_princ_component(krb5_context, krb5_principal, int ); +#endif + /********************************************************************************** Try to verify a ticket using the system keytab... the system keytab has kvno -1 entries, so it's more like what microsoft does... see comment in utils/net_ads.c in the -- cgit From f1fd211e80732f66ca94604d8132d9f31dc5b717 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 20 Aug 2004 20:18:28 +0000 Subject: r1967: Fix a couple of krb5-DEBUG-messages. Guenther (This used to be commit 86a61c86a49a7e4d67e61201458c9b0229fb0825) --- source3/libads/kerberos.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 97b895a241..327a76826e 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -146,7 +146,8 @@ int ads_kdestroy(const char *cc_name) krb5_ccache cc = NULL; if ((code = krb5_init_context (&ctx))) { - DEBUG(3, ("ads_kdestroy: kdb5_init_context rc=%d\n", code)); + DEBUG(3, ("ads_kdestroy: kdb5_init_context failed: %s\n", + error_message(code))); return code; } @@ -157,15 +158,16 @@ int ads_kdestroy(const char *cc_name) } } else { if ((code = krb5_cc_resolve(ctx, cc_name, &cc))) { - DEBUG(3, ("ads_kdestroy: krb5_cc_resolve rc=%d\n", - code)); + DEBUG(3, ("ads_kdestroy: krb5_cc_resolve failed: %s\n", + error_message(code))); krb5_free_context(ctx); return code; } } if ((code = krb5_cc_destroy (ctx, cc))) { - DEBUG(3, ("ads_kdestroy: krb5_cc_destroy rc=%d\n", code)); + DEBUG(3, ("ads_kdestroy: krb5_cc_destroy failed: %s\n", + error_message(code))); } krb5_free_context (ctx); -- cgit From 725d93954896052e24a6870e9e5f14106063fe78 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 27 Aug 2004 16:15:23 +0000 Subject: r2091: only use sAMAccountName and not userPrincipalName since the breaks winbindd (lookup_name() only works with the sAMAccountName) -- *please* test this change. My tests all pass but there is probably something I missed (This used to be commit 2bf08aaa37f41681b3154514792bf29a3abfdbfd) --- source3/libads/ldap.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 78ea9f1497..d1539b83da 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2184,13 +2184,19 @@ BOOL ads_pull_sd(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, */ char *ads_pull_username(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, void *msg) { +#if 0 /* JERRY */ char *ret, *p; + /* lookup_name() only works on the sAMAccountName to + returning the username portion of userPrincipalName + breaks winbindd_getpwnam() */ + ret = ads_pull_string(ads, mem_ctx, msg, "userPrincipalName"); if (ret && (p = strchr(ret, '@'))) { *p = 0; return ret; } +#endif return ads_pull_string(ads, mem_ctx, msg, "sAMAccountName"); } -- cgit From 5a8effaaae3c3037ae0f96a942734298950169c6 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 23 Sep 2004 19:24:02 +0000 Subject: r2569: Patch from Rob Foehl : - fix typo in libads/ldap_printer.c:39, ads_find_printer_on_server() (originally libads-typo.patch) - fix leak in printing/nt_printing.c, is_printer_published() (originally is_printer_published-leak.patch) - fix double print_backend_init() calls, now only called from main() - restructuring in printing/nt_printing.c - replaced (un)publish_it() with ads-specific functions - moved common code to nt_printer_publish() - improved error handling in several places - added check_published_printers() in printing/nt_printing.c, to verify that each published printer is actually in the directory at startup - changed calling semantics of mod_a_printer, dump_a_printer, and update_driver_init to be more consistent with the rest of the api and reduce some copying (This used to be commit 50a5a3dbd02acb0d09133b6e42cc37d091ea901d) --- source3/libads/ldap_printer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index 1448074ea0..d8e4cefcfa 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -36,7 +36,7 @@ ADS_STATUS ads_find_printer_on_server(ADS_STRUCT *ads, void **res, status = ads_find_machine_acct(ads, res, servername); if (!ADS_ERR_OK(status)) { - DEBUG(1, ("ads_add_printer: cannot find host %s in ads\n", + DEBUG(1, ("ads_find_printer_on_server: cannot find host %s in ads\n", servername)); return status; } -- cgit From 132879b285e66bff896c761858311d7f5d43e9b6 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 6 Oct 2004 16:21:35 +0000 Subject: r2832: Readd WKGUID-binding to match the correct default-locations of new User-, Group- and Machine-Accounts in Active Directory (this got lost during the last trunk-merge). This way we match e.g. default containers moved by redircmp.exe and redirusr.exe in Windows 2003 and don't blindly default to cn=Users or cn=Computers. Further wkguids can be examied via "net ads search wellknownobjects=*". This should still keep a samba3-client joining a samba4 dc. Fixes Bugzilla #1343. Guenther (This used to be commit 8836621694c95779475fa9a1acf158e5e0577288) --- source3/libads/ldap.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 73 insertions(+), 4 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index d1539b83da..e5d2dfb8d3 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -995,18 +995,87 @@ ADS_STATUS ads_del_dn(ADS_STRUCT *ads, char *del_dn) * Build an org unit string * if org unit is Computers or blank then assume a container, otherwise * assume a \ separated list of organisational units + * @param ads connection to ads server * @param org_unit Organizational unit * @return org unit string - caller must free **/ -char *ads_ou_string(const char *org_unit) -{ - if (!org_unit || !*org_unit || strequal(org_unit, "Computers")) { +char *ads_ou_string(ADS_STRUCT *ads, const char *org_unit) +{ + char *ret = NULL; + + if (!org_unit || !*org_unit) { + + ret = ads_default_ou_string(ads, WELL_KNOWN_GUID_COMPUTERS); + + /* samba4 might not yet respond to a wellknownobject-query */ + return ret ? ret : strdup("cn=Computers"); + } + + if (strequal(org_unit, "Computers")) { return strdup("cn=Computers"); } return ads_build_path(org_unit, "\\/", "ou=", 1); } +/** + * Get a org unit string for a well-known GUID + * @param ads connection to ads server + * @param wknguid Well known GUID + * @return org unit string - caller must free + **/ +char *ads_default_ou_string(ADS_STRUCT *ads, const char *wknguid) +{ + ADS_STATUS status; + void *res; + char *base, *wkn_dn, *ret, **wkn_dn_exp, **bind_dn_exp; + const char *attrs[] = {"distinguishedName", NULL}; + int new_ln, wkn_ln, bind_ln, i; + + if (wknguid == NULL) { + return NULL; + } + + if (asprintf(&base, "", wknguid, ads->config.bind_path ) == -1) { + DEBUG(1, ("asprintf failed!\n")); + return NULL; + } + + status = ads_search_dn(ads, &res, base, attrs); + if (!ADS_ERR_OK(status)) { + DEBUG(1,("Failed while searching for: %s\n", base)); + return NULL; + } + free(base); + + if (ads_count_replies(ads, res) != 1) { + return NULL; + } + + /* substitute the bind-path from the well-known-guid-search result */ + wkn_dn = ads_get_dn(ads, res); + wkn_dn_exp = ldap_explode_dn(wkn_dn, 0); + bind_dn_exp = ldap_explode_dn(ads->config.bind_path, 0); + + for (wkn_ln=0; wkn_dn_exp[wkn_ln]; wkn_ln++) + ; + for (bind_ln=0; bind_dn_exp[bind_ln]; bind_ln++) + ; + + new_ln = wkn_ln - bind_ln; + + ret = wkn_dn_exp[0]; + + for (i=1; i < new_ln; i++) { + char *s; + asprintf(&s, "%s,%s", ret, wkn_dn_exp[i]); + ret = strdup(s); + free(s); + } + + return ret; +} + /** * Adds (appends) an item to an attribute array, rather then * replacing the whole list @@ -1283,7 +1352,7 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *machine_name machine_name)); exists=1; } else { - char *ou_str = ads_ou_string(org_unit); + char *ou_str = ads_ou_string(ads,org_unit); if (!ou_str) { DEBUG(1, ("ads_add_machine_acct: ads_ou_string returned NULL (malloc failure?)\n")); goto done; -- cgit From f8345c1b18904169666955c98474fa2d5894a007 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 27 Oct 2004 00:41:41 +0000 Subject: r3273: Ensure we're consistent in the use of strchr_m for '@'. Jeremy. (This used to be commit 0f3f7b035b37bfc51d3a59d0472003c3d4ac1511) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index e5d2dfb8d3..749274298f 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2261,7 +2261,7 @@ char *ads_pull_username(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, void *msg) breaks winbindd_getpwnam() */ ret = ads_pull_string(ads, mem_ctx, msg, "userPrincipalName"); - if (ret && (p = strchr(ret, '@'))) { + if (ret && (p = strchr_m(ret, '@'))) { *p = 0; return ret; } -- cgit From 0772ddbae1be394c538f1d3529ea84434eadcf97 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 29 Oct 2004 22:38:10 +0000 Subject: r3377: Merge in first part of modified patch from Nalin Dahyabhai for bug #1717.The rest of the code needed to call this patch has not yet been checked in (that's my next task). This has not yet been tested - I'll do this once the rest of the patch is integrated. Jeremy. (This used to be commit 7565019286cf44f43c8066c005b1cd5c1556435f) --- source3/libads/kerberos.c | 555 +++++++++++++++++++++++++++++++++++++++++++- source3/libads/krb5_setpw.c | 2 +- 2 files changed, 549 insertions(+), 8 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 327a76826e..9eb4d9da46 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -3,8 +3,9 @@ kerberos utility library Copyright (C) Andrew Tridgell 2001 Copyright (C) Remus Koos 2001 - - + Copyright (C) Nalin Dahyabhai 2004. + Copyright (C) Jeremy Allison 2004. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or @@ -24,6 +25,8 @@ #ifdef HAVE_KRB5 +#define LIBADS_CCACHE_NAME "MEMORY:libads" + /* we use a prompter to avoid a crash bug in the kerberos libs when dealing with empty passwords @@ -38,7 +41,7 @@ kerb_prompter(krb5_context ctx, void *data, { if (num_prompts == 0) return 0; - memset(prompts[0].reply->data, 0, prompts[0].reply->length); + memset(prompts[0].reply->data, '\0', prompts[0].reply->length); if (prompts[0].reply->length > 0) { if (data) { strncpy(prompts[0].reply->data, data, prompts[0].reply->length-1); @@ -51,10 +54,15 @@ kerb_prompter(krb5_context ctx, void *data, } /* - simulate a kinit, putting the tgt in the default cache location + simulate a kinit, putting the tgt in the given cache location. If cache_name == NULL + place in default cache location. remus@snapserver.com */ -int kerberos_kinit_password(const char *principal, const char *password, int time_offset, time_t *expire_time) +int kerberos_kinit_password(const char *principal, + const char *password, + int time_offset, + time_t *expire_time, + const char *cache_name) { krb5_context ctx = NULL; krb5_error_code code = 0; @@ -69,7 +77,8 @@ int kerberos_kinit_password(const char *principal, const char *password, int tim krb5_set_real_time(ctx, time(NULL) + time_offset, 0); } - if ((code = krb5_cc_default(ctx, &cc))) { + if ((code = krb5_cc_resolve(ctx, cache_name ? + cache_name : krb5_cc_default_name(ctx), &cc))) { krb5_free_context(ctx); return code; } @@ -129,7 +138,8 @@ int ads_kinit_password(ADS_STRUCT *ads) return KRB5_LIBOS_CANTREADPWD; } - ret = kerberos_kinit_password(s, ads->auth.password, ads->auth.time_offset, &ads->auth.expire); + ret = kerberos_kinit_password(s, ads->auth.password, ads->auth.time_offset, + &ads->auth.expire, NULL); if (ret) { DEBUG(0,("kerberos_kinit_password %s failed: %s\n", @@ -174,4 +184,535 @@ int ads_kdestroy(const char *cc_name) return code; } +/************************************************************************ + Routine to fetch the salting principal for a service. Active + Directory may use a non-obvious principal name to generate the salt + when it determines the key to use for encrypting tickets for a service, + and hopefully we detected that when we joined the domain. + ************************************************************************/ + +static char *kerberos_secrets_fetch_salting_principal(const char *service, int enctype) +{ + char *key = NULL; + char *ret = NULL; + + asprintf(&key, "%s/%s/enctype=%d", SECRETS_SALTING_PRINCIPAL, service, enctype); + if (!key) { + return NULL; + } + ret = (char *)secrets_fetch(key, NULL); + SAFE_FREE(key); + return ret; +} + +/************************************************************************ + Routine to get the salting principal for this service. Active + Directory may use a non-obvious principal name to generate the salt + when it determines the key to use for encrypting tickets for a service, + and hopefully we detected that when we joined the domain. + Caller must free if return is not null. + ************************************************************************/ + +krb5_principal kerberos_fetch_salt_princ_for_host_princ(krb5_context context, + krb5_principal host_princ, + int enctype) +{ + char *unparsed_name = NULL, *salt_princ_s = NULL; + krb5_principal ret_princ = NULL; + + if (krb5_unparse_name(context, host_princ, &unparsed_name) != 0) { + return (krb5_principal)NULL; + } + + if ((salt_princ_s = kerberos_secrets_fetch_salting_principal(unparsed_name, enctype)) == NULL) { + krb5_free_unparsed_name(context, unparsed_name); + return (krb5_principal)NULL; + } + + if (krb5_parse_name(context, salt_princ_s, &ret_princ) != 0) { + krb5_free_unparsed_name(context, unparsed_name); + SAFE_FREE(salt_princ_s); + return (krb5_principal)NULL; + } + krb5_free_unparsed_name(context, unparsed_name); + SAFE_FREE(salt_princ_s); + return ret_princ; +} + +/************************************************************************ + Routine to set the salting principal for this service. Active + Directory may use a non-obvious principal name to generate the salt + when it determines the key to use for encrypting tickets for a service, + and hopefully we detected that when we joined the domain. + Setting principal to NULL deletes this entry. + ************************************************************************/ + +BOOL kerberos_secrets_store_salting_principal(const char *service, + int enctype, + const char *principal) +{ + char *key = NULL; + BOOL ret = False; + krb5_context context = NULL; + krb5_principal princ = NULL; + char *princ_s = NULL; + char *unparsed_name = NULL; + + krb5_init_context(&context); + if (!context) { + return False; + } + if (strchr_m(service, '@')) { + asprintf(&princ_s, "%s", service); + } else { + asprintf(&princ_s, "%s@%s", service, lp_realm()); + } + + if (krb5_parse_name(context, princ_s, &princ) != 0) { + goto out; + + } + if (krb5_unparse_name(context, princ, &unparsed_name) != 0) { + goto out; + } + + asprintf(&key, "%s/%s/enctype=%d", SECRETS_SALTING_PRINCIPAL, unparsed_name, enctype); + if (!key) { + goto out; + } + + if ((principal != NULL) && (strlen(principal) > 0)) { + ret = secrets_store(key, principal, strlen(principal) + 1); + } else { + ret = secrets_delete(key); + } + + out: + + SAFE_FREE(key); + SAFE_FREE(princ_s); + + if (unparsed_name) { + krb5_free_unparsed_name(context, unparsed_name); + } + if (context) { + krb5_free_context(context); + } + + return ret; +} + +/************************************************************************ + Routine to get initial credentials as a service ticket for the local machine. + Returns a buffer initialized with krb5_mk_req_extended. + ************************************************************************/ + +static krb5_error_code get_service_ticket(krb5_context ctx, + krb5_ccache ccache, + const char *service_principal, + int enctype, + krb5_data *p_outbuf) +{ + krb5_creds creds, *new_creds = NULL; + char *service_s = NULL; + char *machine_account = NULL, *password = NULL; + krb5_data in_data; + krb5_auth_context auth_context = NULL; + krb5_error_code err = 0; + + asprintf(&machine_account, "%s$@%s", global_myname(), lp_realm()); + if (machine_account == NULL) { + goto out; + } + password = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL); + if (password == NULL) { + goto out; + } + if ((err = kerberos_kinit_password(machine_account, password, 0, NULL, LIBADS_CCACHE_NAME)) != 0) { + DEBUG(0,("get_service_ticket: kerberos_kinit_password %s@%s failed: %s\n", + machine_account, + lp_realm(), + error_message(err))); + goto out; + } + + /* Ok - the above call has gotten a TGT. Now we need to get a service + ticket to ourselves. */ + + /* Set up the enctype and client and server principal fields for krb5_get_credentials. */ + memset(&creds, '\0', sizeof(creds)); + kerberos_set_creds_enctype(&creds, enctype); + + if ((err = krb5_cc_get_principal(ctx, ccache, &creds.client))) { + DEBUG(3, ("get_service_ticket: krb5_cc_get_principal failed: %s\n", + error_message(err))); + goto out; + } + + if (strchr_m(service_principal, '@')) { + asprintf(&service_s, "%s", service_principal); + } else { + asprintf(&service_s, "%s@%s", service_principal, lp_realm()); + } + + if ((err = krb5_parse_name(ctx, service_s, &creds.server))) { + DEBUG(0,("get_service_ticket: krb5_parse_name %s failed: %s\n", + service_s, error_message(err))); + goto out; + } + + if ((err = krb5_get_credentials(ctx, 0, ccache, &creds, &new_creds))) { + DEBUG(5,("get_service_ticket: krb5_get_credentials for %s failed: %s\n", + service_s, error_message(err))); + goto out; + } + + memset(&in_data, '\0', sizeof(in_data)); + if ((err = krb5_mk_req_extended(ctx, &auth_context, 0, &in_data, + new_creds, p_outbuf)) != 0) { + DEBUG(0,("get_service_ticket: krb5_mk_req_extended failed: %s\n", + error_message(err))); + goto out; + } + + out: + + if (auth_context) { + krb5_auth_con_free(ctx, auth_context); + } + if (new_creds) { + krb5_free_creds(ctx, new_creds); + } + if (creds.server) { + krb5_free_principal(ctx, creds.server); + } + if (creds.client) { + krb5_free_principal(ctx, creds.client); + } + + SAFE_FREE(service_s); + SAFE_FREE(password); + SAFE_FREE(machine_account); + return err; +} + +/************************************************************************ + Check if the machine password can be used in conjunction with the salting_principal + to generate a key which will successfully decrypt the AP_REQ already + gotten as a message to the local machine. + ************************************************************************/ + +static BOOL verify_service_password(krb5_context ctx, + int enctype, + const char *salting_principal, + krb5_data *in_data) +{ + BOOL ret = False; + krb5_principal salting_kprinc = NULL; + krb5_ticket *ticket = NULL; + krb5_keyblock key; + krb5_data passdata; + char *salting_s = NULL; + char *machine_account = NULL, *password = NULL; + krb5_auth_context auth_context = NULL; + krb5_error_code err; + + memset(&passdata, '\0', sizeof(passdata)); + memset(&key, '\0', sizeof(key)); + + asprintf(&machine_account, "%s$@%s", global_myname(), lp_realm()); + if (machine_account == NULL) { + goto out; + } + password = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL); + if (password == NULL) { + goto out; + } + + if (strchr_m(salting_principal, '@')) { + asprintf(&salting_s, "%s", salting_principal); + } else { + asprintf(&salting_s, "%s@%s", salting_principal, lp_realm()); + } + + if ((err = krb5_parse_name(ctx, salting_s, &salting_kprinc))) { + DEBUG(0,("verify_service_password: krb5_parse_name %s failed: %s\n", + salting_s, error_message(err))); + goto out; + } + + passdata.length = strlen(password); + passdata.data = (char*)password; + if ((err = create_kerberos_key_from_string_direct(ctx, salting_kprinc, &passdata, &key, enctype))) { + DEBUG(0,("verify_service_password: create_kerberos_key_from_string %d failed: %s\n", + enctype, error_message(err))); + goto out; + } + + if ((err = krb5_auth_con_init(ctx, &auth_context)) != 0) { + DEBUG(0,("verify_service_password: krb5_auth_con_init failed %s\n", error_message(err))); + goto out; + } + + if ((err = krb5_auth_con_setuseruserkey(ctx, auth_context, &key)) != 0) { + DEBUG(0,("verify_service_password: krb5_auth_con_setuseruserkey failed %s\n", error_message(err))); + goto out; + } + + if (!(err = krb5_rd_req(ctx, &auth_context, in_data, NULL, NULL, NULL, &ticket))) { + DEBUG(10,("verify_service_password: decrypted message with enctype %u salt %s!\n", + (unsigned int)enctype, salting_s)); + ret = True; + } + + out: + + memset(&passdata, 0, sizeof(passdata)); + krb5_free_keyblock_contents(ctx, &key); + if (ticket != NULL) { + krb5_free_ticket(ctx, ticket); + } + if (salting_kprinc) { + krb5_free_principal(ctx, salting_kprinc); + } + SAFE_FREE(salting_s); + SAFE_FREE(password); + SAFE_FREE(machine_account); + return ret; +} + +/************************************************************************ + * + * From the current draft of kerberos-clarifications: + * + * It is not possible to reliably generate a user's key given a pass + * phrase without contacting the KDC, since it will not be known + * whether alternate salt or parameter values are required. + * + * And because our server has a password, we have this exact problem. We + * make multiple guesses as to which principal name provides the salt which + * the KDC is using. + * + ************************************************************************/ + +static void kerberos_derive_salting_principal_for_enctype(const char *service_principal, + krb5_context ctx, + krb5_ccache ccache, + krb5_enctype enctype, + krb5_enctype *enctypes) +{ + char *salting_principals[3] = {NULL, NULL, NULL}, *second_principal = NULL; + krb5_error_code err = 0; + krb5_data outbuf; + int i, j; + + memset(&outbuf, '\0', sizeof(outbuf)); + + /* Check that the service_principal is useful. */ + if ((service_principal == NULL) || (strlen(service_principal) == 0)) { + return; + } + + /* Generate our first guess -- the principal as-given. */ + asprintf(&salting_principals[0], "%s", service_principal); + if ((salting_principals[0] == NULL) || (strlen(salting_principals[0]) == 0)) { + return; + } + + /* Generate our second guess -- the computer's principal, as Win2k3. */ + asprintf(&second_principal, "host/%s.%s", global_myname(), lp_realm()); + if (second_principal != NULL) { + strlower_m(second_principal); + asprintf(&salting_principals[1], "%s@%s", second_principal, lp_realm()); + SAFE_FREE(second_principal); + } + if ((salting_principals[1] == NULL) || (strlen(salting_principals[1]) == 0)) { + goto out; + } + + /* Generate our third guess -- the computer's principal, as Win2k. */ + asprintf(&second_principal, "HOST/%s", global_myname()); + if (second_principal != NULL) { + strlower_m(second_principal + 5); + asprintf(&salting_principals[2], "%s@%s", + second_principal, lp_realm()); + SAFE_FREE(second_principal); + } + if ((salting_principals[2] == NULL) || (strlen(salting_principals[2]) == 0)) { + goto out; + } + + /* Get a service ticket for ourselves into our memory ccache. */ + /* This will commonly fail if there is no principal by that name (and we're trying + many names). So don't print a debug 0 error. */ + + if ((err = get_service_ticket(ctx, ccache, service_principal, enctype, &outbuf)) != 0) { + DEBUG(3, ("verify_service_password: get_service_ticket failed: %s\n", + error_message(err))); + goto out; + } + + /* At this point we have a message to ourselves, salted only the KDC knows how. We + have to work out what that salting is. */ + + /* Try and find the correct salting principal. */ + for (i = 0; i < sizeof(salting_principals) / sizeof(salting_principals[i]); i++) { + if (verify_service_password(ctx, enctype, salting_principals[i], &outbuf)) { + break; + } + } + + /* If we failed to get a match, return. */ + if (i >= sizeof(salting_principals) / sizeof(salting_principals[i])) { + goto out; + } + + /* If we succeeded, store the principal for use for all enctypes which + * share the same cipher and string-to-key function. Doing this here + * allows servers which just pass a keytab to krb5_rd_req() to work + * correctly. */ + for (j = 0; enctypes[j] != 0; j++) { + if (enctype != enctypes[j]) { + /* If this enctype isn't compatible with the one which + * we used, skip it. */ + + if (!kerberos_compatible_enctypes(ctx, enctypes[j], enctype)) + continue; + } + /* If the principal which gives us the proper salt is the one + * which we would normally guess, don't bother noting anything + * in the secrets tdb. */ + if (strcmp(service_principal, salting_principals[i]) != 0) { + kerberos_secrets_store_salting_principal(service_principal, + enctypes[j], + salting_principals[i]); + } + } + + out : + + kerberos_free_data_contents(ctx, &outbuf); + SAFE_FREE(salting_principals[0]); + SAFE_FREE(salting_principals[1]); + SAFE_FREE(salting_principals[2]); + SAFE_FREE(second_principal); +} + +/************************************************************************ + Go through all the possible enctypes for this principal. + ************************************************************************/ + +void kerberos_derive_salting_principal(krb5_context context, + krb5_ccache ccache, + krb5_enctype *enctypes, + char *service_principal) +{ + int i; + + /* Try for each enctype separately, because the rules are + * different for different enctypes. */ + for (i = 0; enctypes[i] != 0; i++) { + /* Delete secrets entry first. */ + kerberos_secrets_store_salting_principal(service_principal, 0, NULL); +#ifdef ENCTYPE_ARCFOUR_HMAC + if (enctypes[i] == ENCTYPE_ARCFOUR_HMAC) { + /* Of course this'll always work, so just save + * ourselves the effort. */ + continue; + } +#endif + /* Try to figure out what's going on with this + * principal. */ + kerberos_derive_salting_principal_for_enctype(service_principal, + context, + ccache, + enctypes[i], + enctypes); + } +} + +/************************************************************************ + Core function to try and determine what salt is being used for any keytab + keys. + ************************************************************************/ + +BOOL kerberos_derive_cifs_salting_principals(void) +{ + fstring my_fqdn; + char *service = NULL; + krb5_context context = NULL; + krb5_enctype *enctypes = NULL; + krb5_ccache ccache = NULL; + krb5_error_code ret = 0; + BOOL retval = False; + + initialize_krb5_error_table(); + if ((ret = krb5_init_context(&context)) != 0) { + DEBUG(1,("kerberos_derive_cifs_salting_principals: krb5_init_context failed. %s\n", + error_message(ret))); + return False; + } + if ((ret = get_kerberos_allowed_etypes(context, &enctypes)) != 0) { + DEBUG(1,("kerberos_derive_cifs_salting_principals: get_kerberos_allowed_etypes failed. %s\n", + error_message(ret))); + goto out; + } + + if ((ret = krb5_cc_resolve(context, LIBADS_CCACHE_NAME, &ccache)) != 0) { + DEBUG(3, ("get_service_ticket: krb5_cc_resolve for %s failed: %s\n", + LIBADS_CCACHE_NAME, error_message(ret))); + goto out; + } + + if (asprintf(&service, "%s$", global_myname()) != -1) { + strlower_m(service); + kerberos_derive_salting_principal(context, ccache, enctypes, service); + SAFE_FREE(service); + } + if (asprintf(&service, "cifs/%s", global_myname()) != -1) { + strlower_m(service); + kerberos_derive_salting_principal(context, ccache, enctypes, service); + SAFE_FREE(service); + } + if (asprintf(&service, "host/%s", global_myname()) != -1) { + strlower_m(service); + kerberos_derive_salting_principal(context, ccache, enctypes, service); + SAFE_FREE(service); + } + if (asprintf(&service, "cifs/%s.%s", global_myname(), lp_realm()) != -1) { + strlower_m(service); + kerberos_derive_salting_principal(context, ccache, enctypes, service); + SAFE_FREE(service); + } + if (asprintf(&service, "host/%s.%s", global_myname(), lp_realm()) != -1) { + strlower_m(service); + kerberos_derive_salting_principal(context, ccache, enctypes, service); + SAFE_FREE(service); + } + name_to_fqdn(my_fqdn, global_myname()); + if (asprintf(&service, "cifs/%s", my_fqdn) != -1) { + strlower_m(service); + kerberos_derive_salting_principal(context, ccache, enctypes, service); + SAFE_FREE(service); + } + if (asprintf(&service, "host/%s", my_fqdn) != -1) { + strlower_m(service); + kerberos_derive_salting_principal(context, ccache, enctypes, service); + SAFE_FREE(service); + } + + retval = True; + + out: + if (enctypes) { + free_kerberos_etypes(context, enctypes); + } + if (ccache) { + krb5_cc_destroy(context, ccache); + } + if (context) { + krb5_free_context(context); + } + return retval; +} #endif diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 84595212e6..385c1f02aa 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -667,7 +667,7 @@ ADS_STATUS kerberos_set_password(const char *kpasswd_server, { int ret; - if ((ret = kerberos_kinit_password(auth_principal, auth_password, time_offset, NULL))) { + if ((ret = kerberos_kinit_password(auth_principal, auth_password, time_offset, NULL, NULL))) { DEBUG(1,("Failed kinit for principal %s (%s)\n", auth_principal, error_message(ret))); return ADS_ERROR_KRB5(ret); } -- cgit From cf47845b1c2e83d49f32bdfc455cd9114a234df8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 30 Oct 2004 00:34:58 +0000 Subject: r3379: More merging of kerberos keytab and salting fixes from Nalin Dahyabhai (bugid #1717). Jeremy. (This used to be commit 30b8807cf6d5c3c5b9947a7e841d69f0b22eb019) --- source3/libads/kerberos.c | 15 +++++++ source3/libads/kerberos_keytab.c | 89 +++++++++++++++++++++++++++++++++------- 2 files changed, 89 insertions(+), 15 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 9eb4d9da46..dc1edb3cde 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -608,6 +608,17 @@ void kerberos_derive_salting_principal(krb5_context context, char *service_principal) { int i; + BOOL free_ccache = False; + + if (ccache == NULL) { + krb5_error_code ret; + if ((ret = krb5_cc_resolve(context, LIBADS_CCACHE_NAME, &ccache)) != 0) { + DEBUG(0, ("kerberos_derive_salting_principal: krb5_cc_resolve for %s failed: %s\n", + LIBADS_CCACHE_NAME, error_message(ret))); + return; + } + free_ccache = True; + } /* Try for each enctype separately, because the rules are * different for different enctypes. */ @@ -629,6 +640,10 @@ void kerberos_derive_salting_principal(krb5_context context, enctypes[i], enctypes); } + + if (free_ccache && ccache) { + krb5_cc_close(context, ccache); + } } /************************************************************************ diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c index eec5f104fd..5ece6e6ab2 100644 --- a/source3/libads/kerberos_keytab.c +++ b/source3/libads/kerberos_keytab.c @@ -101,7 +101,34 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc) /* Construct our principal */ name_to_fqdn(my_fqdn, global_myname()); strlower_m(my_fqdn); - asprintf(&princ_s, "%s/%s@%s", srvPrinc, my_fqdn, lp_realm()); + + if (strchr_m(srvPrinc, '@')) { + /* It's a fully-named principal. */ + asprintf(&princ_s, "%s", srvPrinc); + } else if (srvPrinc[strlen(srvPrinc)-1] == '$') { + /* It's the machine account, as used by smbclient clients. */ + asprintf(&princ_s, "%s@%s", srvPrinc, lp_realm()); + } else { + /* It's a normal service principal. Add the SPN now so that we + * can obtain credentials for it and double-check the salt value + * used to generate the service's keys. */ + asprintf(&princ_s, "%s/%s@%s", srvPrinc, my_fqdn, lp_realm()); + /* Update the directory with the SPN */ + DEBUG(3,("ads_keytab_add_entry: Attempting to add/update '%s'\n", princ_s)); + if (!ADS_ERR_OK(ads_add_service_principal_name(ads, global_myname(), srvPrinc))) { + DEBUG(1,("ads_keytab_add_entry: ads_add_service_principal_name failed.\n")); + goto out; + } + } + + ret = get_kerberos_allowed_etypes(context,&enctypes); + if (ret) { + DEBUG(1,("ads_keytab_add_entry: get_kerberos_allowed_etypes failed (%s)\n",error_message(ret))); + goto out; + } + + /* Guess at how the KDC is salting keys for this principal. */ + kerberos_derive_salting_principal(context, NULL, enctypes, princ_s); ret = krb5_parse_name(context, princ_s, &princ); if (ret) { @@ -201,12 +228,6 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc) /* If we get here, we have deleted all the old entries with kvno's not equal to the current kvno-1. */ - ret = get_kerberos_allowed_etypes(context,&enctypes); - if (ret) { - DEBUG(1,("ads_keytab_add_entry: get_kerberos_allowed_etypes failed (%s)\n",error_message(ret))); - goto out; - } - /* Now add keytab entries for all encryption types */ for (i = 0; enctypes[i]; i++) { krb5_keyblock *keyp; @@ -241,13 +262,6 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc) krb5_kt_close(context, keytab); keytab = NULL; /* Done with keytab now. No double free. */ - /* Update the LDAP with the SPN */ - DEBUG(3,("ads_keytab_add_entry: Attempting to add/update '%s'\n", princ_s)); - if (!ADS_ERR_OK(ads_add_service_principal_name(ads, global_myname(), srvPrinc))) { - DEBUG(1,("ads_keytab_add_entry: ads_add_service_principcal_name failed.\n")); - goto out; - } - out: SAFE_FREE(principal); @@ -410,8 +424,9 @@ int ads_keytab_create_default(ADS_STRUCT *ads) krb5_kt_cursor cursor; krb5_keytab_entry kt_entry; krb5_kvno kvno; + fstring my_fqdn, my_Fqdn, my_name, my_NAME; int i, found = 0; - char **oldEntries = NULL; + char **oldEntries = NULL, *princ_s[18];; ret = ads_keytab_add_entry(ads, "host"); if (ret) { @@ -424,6 +439,45 @@ int ads_keytab_create_default(ADS_STRUCT *ads) return ret; } + fstrcpy(my_name, global_myname()); + strlower_m(my_name); + fstrcpy(my_NAME, global_myname()); + strupper_m(my_NAME); + name_to_fqdn(my_Fqdn, global_myname()); + strlower_m(my_Fqdn); + memcpy(my_Fqdn, my_NAME, strlen(my_NAME)); + name_to_fqdn(my_fqdn, global_myname()); + strlower_m(my_fqdn); + + asprintf(&princ_s[0], "%s$@%s", my_name, lp_realm()); + asprintf(&princ_s[1], "%s$@%s", my_NAME, lp_realm()); + asprintf(&princ_s[2], "host/%s@%s", my_name, lp_realm()); + asprintf(&princ_s[3], "host/%s@%s", my_NAME, lp_realm()); + asprintf(&princ_s[4], "host/%s@%s", my_fqdn, lp_realm()); + asprintf(&princ_s[5], "host/%s@%s", my_Fqdn, lp_realm()); + asprintf(&princ_s[6], "HOST/%s@%s", my_name, lp_realm()); + asprintf(&princ_s[7], "HOST/%s@%s", my_NAME, lp_realm()); + asprintf(&princ_s[8], "HOST/%s@%s", my_fqdn, lp_realm()); + asprintf(&princ_s[9], "HOST/%s@%s", my_Fqdn, lp_realm()); + asprintf(&princ_s[10], "cifs/%s@%s", my_name, lp_realm()); + asprintf(&princ_s[11], "cifs/%s@%s", my_NAME, lp_realm()); + asprintf(&princ_s[12], "cifs/%s@%s", my_fqdn, lp_realm()); + asprintf(&princ_s[13], "cifs/%s@%s", my_Fqdn, lp_realm()); + asprintf(&princ_s[14], "CIFS/%s@%s", my_name, lp_realm()); + asprintf(&princ_s[15], "CIFS/%s@%s", my_NAME, lp_realm()); + asprintf(&princ_s[16], "CIFS/%s@%s", my_fqdn, lp_realm()); + asprintf(&princ_s[17], "CIFS/%s@%s", my_Fqdn, lp_realm()); + + for (i = 0; i < sizeof(princ_s) / sizeof(princ_s[0]); i++) { + if (princ_s[i] != NULL) { + ret = ads_keytab_add_entry(ads, princ_s[i]); + if (ret != 0) { + DEBUG(1,("ads_keytab_create_default: ads_keytab_add_entry failed while adding '%s'.\n", princ_s[i])); + } + SAFE_FREE(princ_s[i]); + } + } + kvno = (krb5_kvno) ads_get_kvno(ads, global_myname()); if (kvno == -1) { DEBUG(1,("ads_keytab_create_default: ads_get_kvno failed to determine the system's kvno.\n")); @@ -495,6 +549,11 @@ int ads_keytab_create_default(ADS_STRUCT *ads) * or mb strings into account. Maybe this is because they assume utf8 ? * In this case we may need to convert from utf8 to mb charset here ? JRA. */ + p = strchr_m(ktprinc, '@'); + if (p) { + *p = '\0'; + } + p = strchr_m(ktprinc, '/'); if (p) { *p = '\0'; -- cgit From 2d4725cfa6f93c5cf9e355b3b1ad199e7518b531 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 30 Oct 2004 01:32:05 +0000 Subject: r3381: More merging of the #1717 patch. Fixup some erroneous assumptions about memcpy's into fqdn names. I think the original intent was to create MYNAME.fqdn.tail.part. Will need testing to see I haven't broken keytab support. Jeremy. (This used to be commit 82acf83040654eb8b7e261518a3e5eb9caea7750) --- source3/libads/kerberos_keytab.c | 13 +++- source3/libads/kerberos_verify.c | 126 +++++++++++++++++++++------------------ 2 files changed, 77 insertions(+), 62 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c index 5ece6e6ab2..90f5a376d6 100644 --- a/source3/libads/kerberos_keytab.c +++ b/source3/libads/kerberos_keytab.c @@ -425,6 +425,7 @@ int ads_keytab_create_default(ADS_STRUCT *ads) krb5_keytab_entry kt_entry; krb5_kvno kvno; fstring my_fqdn, my_Fqdn, my_name, my_NAME; + char *p_fqdn; int i, found = 0; char **oldEntries = NULL, *princ_s[18];; @@ -441,14 +442,20 @@ int ads_keytab_create_default(ADS_STRUCT *ads) fstrcpy(my_name, global_myname()); strlower_m(my_name); + fstrcpy(my_NAME, global_myname()); strupper_m(my_NAME); - name_to_fqdn(my_Fqdn, global_myname()); - strlower_m(my_Fqdn); - memcpy(my_Fqdn, my_NAME, strlen(my_NAME)); + + my_fqdn[0] = '\0'; name_to_fqdn(my_fqdn, global_myname()); strlower_m(my_fqdn); + p_fqdn = strchr_m(my_fqdn, '.'); + fstrcpy(my_Fqdn, my_NAME); + if (p_fqdn) { + fstrcat(my_Fqdn, p_fqdn); + } + asprintf(&princ_s[0], "%s$@%s", my_name, lp_realm()); asprintf(&princ_s[1], "%s$@%s", my_NAME, lp_realm()); asprintf(&princ_s[2], "host/%s@%s", my_name, lp_realm()); diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 961b92ccc6..140d7550ad 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -41,14 +41,13 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut { krb5_error_code ret = 0; BOOL auth_ok = False; - krb5_keytab keytab = NULL; - krb5_kt_cursor cursor; - krb5_keytab_entry kt_entry; - char *princ_name = NULL; - - ZERO_STRUCT(kt_entry); - ZERO_STRUCT(cursor); + fstring my_fqdn, my_name; + fstring my_Fqdn, my_NAME; + char *p_fqdn; + char *host_princ_s[18]; + krb5_principal host_princ; + int i; ret = krb5_kt_default(context, &keytab); if (ret) { @@ -56,69 +55,78 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut goto out; } - ret = krb5_kt_start_seq_get(context, keytab, &cursor); - if (ret) { - DEBUG(1, ("ads_keytab_verify_ticket: krb5_kt_start_seq_get failed (%s)\n", error_message(ret))); - goto out; - } - - while (!krb5_kt_next_entry(context, keytab, &kt_entry, &cursor)) { - ret = krb5_unparse_name(context, kt_entry.principal, &princ_name); + /* Generate the list of principal names which we expect clients might + * want to use for authenticating to the file service. */ + + fstrcpy(my_name, global_myname()); + strlower_m(my_name); + + fstrcpy(my_NAME, global_myname()); + strupper_m(my_NAME); + + my_fqdn[0] = '\0'; + name_to_fqdn(my_fqdn, global_myname()); + strlower_m(my_fqdn); + + p_fqdn = strchr_m(my_fqdn, '.'); + fstrcpy(my_Fqdn, my_NAME); + if (p_fqdn) { + fstrcat(my_Fqdn, p_fqdn); + } + + asprintf(&host_princ_s[0], "%s$@%s", my_name, lp_realm()); + asprintf(&host_princ_s[1], "%s$@%s", my_NAME, lp_realm()); + asprintf(&host_princ_s[2], "host/%s@%s", my_name, lp_realm()); + asprintf(&host_princ_s[3], "host/%s@%s", my_NAME, lp_realm()); + asprintf(&host_princ_s[4], "host/%s@%s", my_fqdn, lp_realm()); + asprintf(&host_princ_s[5], "host/%s@%s", my_Fqdn, lp_realm()); + asprintf(&host_princ_s[6], "HOST/%s@%s", my_name, lp_realm()); + asprintf(&host_princ_s[7], "HOST/%s@%s", my_NAME, lp_realm()); + asprintf(&host_princ_s[8], "HOST/%s@%s", my_fqdn, lp_realm()); + asprintf(&host_princ_s[9], "HOST/%s@%s", my_Fqdn, lp_realm()); + asprintf(&host_princ_s[10], "cifs/%s@%s", my_name, lp_realm()); + asprintf(&host_princ_s[11], "cifs/%s@%s", my_NAME, lp_realm()); + asprintf(&host_princ_s[12], "cifs/%s@%s", my_fqdn, lp_realm()); + asprintf(&host_princ_s[13], "cifs/%s@%s", my_Fqdn, lp_realm()); + asprintf(&host_princ_s[14], "CIFS/%s@%s", my_name, lp_realm()); + asprintf(&host_princ_s[15], "CIFS/%s@%s", my_NAME, lp_realm()); + asprintf(&host_princ_s[16], "CIFS/%s@%s", my_fqdn, lp_realm()); + asprintf(&host_princ_s[17], "CIFS/%s@%s", my_Fqdn, lp_realm()); + + /* Now try to verify the ticket using the key associated with each of + * the principals which we think clients will expect us to be + * participating as. */ + for (i = 0; i < sizeof(host_princ_s) / sizeof(host_princ_s[0]); i++) { + host_princ = NULL; + ret = krb5_parse_name(context, host_princ_s[i], &host_princ); if (ret) { - DEBUG(1, ("ads_keytab_verify_ticket: krb5_unparse_name failed (%s)\n", error_message(ret))); + DEBUG(1, ("ads_keytab_verify_ticket: krb5_parse_name(%s) failed (%s)\n", + host_princ_s[i], error_message(ret))); goto out; } - /* Look for a CIFS ticket */ - if (!StrnCaseCmp(princ_name, "cifs/", 5)) { -#ifdef HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK - krb5_auth_con_setuseruserkey(context, auth_context, &kt_entry.keyblock); -#else - krb5_auth_con_setuseruserkey(context, auth_context, &kt_entry.key); -#endif - - p_packet->length = ticket->length; - p_packet->data = (krb5_pointer)ticket->data; - - if (!(ret = krb5_rd_req(context, &auth_context, p_packet, NULL, NULL, NULL, pp_tkt))) { - unsigned int keytype; - krb5_free_unparsed_name(context, princ_name); - princ_name = NULL; -#ifdef HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK - keytype = (unsigned int) kt_entry.keyblock.keytype; -#else - keytype = (unsigned int) kt_entry.key.enctype; -#endif - DEBUG(10,("ads_keytab_verify_ticket: enc type [%u] decrypted message !\n", - keytype)); - auth_ok = True; - break; - } - } - krb5_free_unparsed_name(context, princ_name); - princ_name = NULL; + p_packet->length = ticket->length; + p_packet->data = (krb5_pointer)ticket->data; + *pp_tkt = NULL; + ret = krb5_rd_req(context, &auth_context, p_packet, host_princ, keytab, NULL, pp_tkt); + krb5_free_principal(context, host_princ); + if (ret) { + DEBUG(0, ("krb5_rd_req(%s) failed: %s\n", host_princ_s[i], error_message(ret))); + } else { + DEBUG(10,("krb5_rd_req succeeded for principal %s\n", host_princ_s[i])); + auth_ok = True; + break; + } } - if (ret && ret != KRB5_KT_END) { - /* This failed because something went wrong, not because the keytab file was empty. */ - DEBUG(1, ("ads_keytab_verify_ticket: krb5_kt_next_entry failed (%s)\n", error_message(ret))); - goto out; + + for (i = 0; i < sizeof(host_princ_s) / sizeof(host_princ_s[0]); i++) { + SAFE_FREE(host_princ_s[i]); } out: - if (princ_name) { - krb5_free_unparsed_name(context, princ_name); - } - { - krb5_kt_cursor zero_csr; - ZERO_STRUCT(zero_csr); - if ((memcmp(&cursor, &zero_csr, sizeof(krb5_kt_cursor)) != 0) && keytab) { - krb5_kt_end_seq_get(context, keytab, &cursor); - } - } if (keytab) { krb5_kt_close(context, keytab); } - return auth_ok; } -- cgit From 428ca3998bc84aba166adb6c0eae3f20b2ad782c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 1 Nov 2004 16:18:14 +0000 Subject: r3436: Fix build with recent heimdal-versions (0.6.3) as pointed out by Luke Mewburn and close Bugzilla #1661. Leaving the old define for KRB5_KPASSWD_VERS_SETPW (added by Antti Andreimann) as fallback when the library does not provide one. Guenther (This used to be commit 00598877dfb7aab48d1b5d58b3a69ed2dd8a36a8) --- source3/libads/krb5_setpw.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 385c1f02aa..a45bf23610 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -25,7 +25,9 @@ #define DEFAULT_KPASSWD_PORT 464 #define KRB5_KPASSWD_VERS_CHANGEPW 1 +#ifndef KRB5_KPASSWD_VERS_SETPW #define KRB5_KPASSWD_VERS_SETPW 2 +#endif #define KRB5_KPASSWD_VERS_SETPW_MS 0xff80 #define KRB5_KPASSWD_ACCESSDENIED 5 #define KRB5_KPASSWD_BAD_VERSION 6 -- cgit From 3688bb079e8d817dcfc3b9e5eb9d07e7b95a806f Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 1 Nov 2004 19:35:55 +0000 Subject: r3439: Finally fix build for platforms without kerberos. Guenther (This used to be commit 05619cfdbf814e5c79e65934b82424eca00c76c4) --- source3/libads/kerberos.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index dc1edb3cde..6004bc8098 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -247,7 +247,7 @@ krb5_principal kerberos_fetch_salt_princ_for_host_princ(krb5_context context, Setting principal to NULL deletes this entry. ************************************************************************/ -BOOL kerberos_secrets_store_salting_principal(const char *service, + BOOL kerberos_secrets_store_salting_principal(const char *service, int enctype, const char *principal) { @@ -602,7 +602,7 @@ static void kerberos_derive_salting_principal_for_enctype(const char *service_pr Go through all the possible enctypes for this principal. ************************************************************************/ -void kerberos_derive_salting_principal(krb5_context context, + void kerberos_derive_salting_principal(krb5_context context, krb5_ccache ccache, krb5_enctype *enctypes, char *service_principal) -- cgit From 37117a10142e6ad320f994cab4442b12529685ee Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 2 Nov 2004 02:21:26 +0000 Subject: r3451: Finish off kerberos salting patch. Needs testing ! Jeremy. (This used to be commit ff4cb6b5e80731856d6f3f7eebd8fc23902e3580) --- source3/libads/kerberos_verify.c | 5 ++-- source3/libads/util.c | 58 ++++++++++++++++++++++------------------ 2 files changed, 34 insertions(+), 29 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 140d7550ad..8524fc5d05 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -262,9 +262,8 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, goto out; } - name_to_fqdn(myname, global_myname()); - strlower_m(myname); - asprintf(&host_princ_s, "host/%s@%s", myname, lp_realm()); + asprintf(&host_princ_s, "%s$", global_myname()); + strlower_m(host_princ_s); ret = krb5_parse_name(context, host_princ_s, &host_princ); if (ret) { DEBUG(1,("ads_verify_ticket: krb5_parse_name(%s) failed (%s)\n", diff --git a/source3/libads/util.c b/source3/libads/util.c index 9912a7ba83..f5b8873538 100644 --- a/source3/libads/util.c +++ b/source3/libads/util.c @@ -24,39 +24,45 @@ ADS_STATUS ads_change_trust_account_password(ADS_STRUCT *ads, char *host_principal) { - char *tmp_password; - char *password; - char *new_password; - char *service_principal; - ADS_STATUS ret; - uint32 sec_channel_type; + char *password; + char *new_password; + char *service_principal; + ADS_STATUS ret; + uint32 sec_channel_type; - if ((password = secrets_fetch_machine_password(lp_workgroup(), NULL, &sec_channel_type)) == NULL) { - DEBUG(1,("Failed to retrieve password for principal %s\n", host_principal)); - return ADS_ERROR_SYSTEM(ENOENT); - } + if ((password = secrets_fetch_machine_password(lp_workgroup(), NULL, &sec_channel_type)) == NULL) { + DEBUG(1,("Failed to retrieve password for principal %s\n", host_principal)); + return ADS_ERROR_SYSTEM(ENOENT); + } - tmp_password = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH); - new_password = strdup(tmp_password); + new_password = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH); - asprintf(&service_principal, "HOST/%s", host_principal); + asprintf(&service_principal, "HOST/%s", host_principal); - ret = kerberos_set_password(ads->auth.kdc_server, service_principal, password, service_principal, new_password, ads->auth.time_offset); + ret = kerberos_set_password(ads->auth.kdc_server, service_principal, password, service_principal, new_password, ads->auth.time_offset); - if (!ADS_ERR_OK(ret)) goto failed; + if (!ADS_ERR_OK(ret)) { + goto failed; + } - if (!secrets_store_machine_password(new_password, lp_workgroup(), sec_channel_type)) { - DEBUG(1,("Failed to save machine password\n")); - return ADS_ERROR_SYSTEM(EACCES); - } + if (!secrets_store_machine_password(new_password, lp_workgroup(), sec_channel_type)) { + DEBUG(1,("Failed to save machine password\n")); + ret = ADS_ERROR_SYSTEM(EACCES); + goto failed; + } -failed: - SAFE_FREE(service_principal); - SAFE_FREE(new_password); + /* Determine if the KDC is salting keys for this principal in a + * non-obvious way. */ + if (!kerberos_derive_salting_principal(service_principal)) { + DEBUG(1,("Failed to determine correct salting principal for %s\n", service_principal)); + ret = ADS_ERROR_SYSTEM(EACCES); + goto failed; + } - return ret; +failed: + SAFE_FREE(service_principal); + SAFE_FREE(password); + SAFE_FREE(new_password); + return ret; } - - - #endif -- cgit From 917a53cc5875a7ea0384b906dd262b619eb2178e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 2 Nov 2004 21:28:14 +0000 Subject: r3492: Fixes from testing kerberos salted principal fix. Jeremy. (This used to be commit b356a8fdc5a1ac45f2f7f56a0836e794bdecddc6) --- source3/libads/kerberos.c | 74 +++++++++++++++++++++++++++------------- source3/libads/kerberos_keytab.c | 2 +- 2 files changed, 52 insertions(+), 24 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 6004bc8098..32f5951c9f 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -362,8 +362,8 @@ static krb5_error_code get_service_ticket(krb5_context ctx, } if ((err = krb5_get_credentials(ctx, 0, ccache, &creds, &new_creds))) { - DEBUG(5,("get_service_ticket: krb5_get_credentials for %s failed: %s\n", - service_s, error_message(err))); + DEBUG(5,("get_service_ticket: krb5_get_credentials for %s enctype %d failed: %s\n", + service_s, enctype, error_message(err))); goto out; } @@ -602,23 +602,12 @@ static void kerberos_derive_salting_principal_for_enctype(const char *service_pr Go through all the possible enctypes for this principal. ************************************************************************/ - void kerberos_derive_salting_principal(krb5_context context, +static void kerberos_derive_salting_principal_direct(krb5_context context, krb5_ccache ccache, krb5_enctype *enctypes, char *service_principal) { int i; - BOOL free_ccache = False; - - if (ccache == NULL) { - krb5_error_code ret; - if ((ret = krb5_cc_resolve(context, LIBADS_CCACHE_NAME, &ccache)) != 0) { - DEBUG(0, ("kerberos_derive_salting_principal: krb5_cc_resolve for %s failed: %s\n", - LIBADS_CCACHE_NAME, error_message(ret))); - return; - } - free_ccache = True; - } /* Try for each enctype separately, because the rules are * different for different enctypes. */ @@ -640,9 +629,48 @@ static void kerberos_derive_salting_principal_for_enctype(const char *service_pr enctypes[i], enctypes); } +} - if (free_ccache && ccache) { - krb5_cc_close(context, ccache); +/************************************************************************ + Wrapper function for the above. + ************************************************************************/ + +void kerberos_derive_salting_principal(char *service_principal) +{ + krb5_context context = NULL; + krb5_enctype *enctypes = NULL; + krb5_ccache ccache = NULL; + krb5_error_code ret = 0; + + initialize_krb5_error_table(); + if ((ret = krb5_init_context(&context)) != 0) { + DEBUG(1,("kerberos_derive_cifs_salting_principals: krb5_init_context failed. %s\n", + error_message(ret))); + return; + } + if ((ret = get_kerberos_allowed_etypes(context, &enctypes)) != 0) { + DEBUG(1,("kerberos_derive_cifs_salting_principals: get_kerberos_allowed_etypes failed. %s\n", + error_message(ret))); + goto out; + } + + if ((ret = krb5_cc_resolve(context, LIBADS_CCACHE_NAME, &ccache)) != 0) { + DEBUG(3, ("get_service_ticket: krb5_cc_resolve for %s failed: %s\n", + LIBADS_CCACHE_NAME, error_message(ret))); + goto out; + } + + kerberos_derive_salting_principal_direct(context, ccache, enctypes, service_principal); + + out: + if (enctypes) { + free_kerberos_etypes(context, enctypes); + } + if (ccache) { + krb5_cc_destroy(context, ccache); + } + if (context) { + krb5_free_context(context); } } @@ -681,38 +709,38 @@ BOOL kerberos_derive_cifs_salting_principals(void) if (asprintf(&service, "%s$", global_myname()) != -1) { strlower_m(service); - kerberos_derive_salting_principal(context, ccache, enctypes, service); + kerberos_derive_salting_principal_direct(context, ccache, enctypes, service); SAFE_FREE(service); } if (asprintf(&service, "cifs/%s", global_myname()) != -1) { strlower_m(service); - kerberos_derive_salting_principal(context, ccache, enctypes, service); + kerberos_derive_salting_principal_direct(context, ccache, enctypes, service); SAFE_FREE(service); } if (asprintf(&service, "host/%s", global_myname()) != -1) { strlower_m(service); - kerberos_derive_salting_principal(context, ccache, enctypes, service); + kerberos_derive_salting_principal_direct(context, ccache, enctypes, service); SAFE_FREE(service); } if (asprintf(&service, "cifs/%s.%s", global_myname(), lp_realm()) != -1) { strlower_m(service); - kerberos_derive_salting_principal(context, ccache, enctypes, service); + kerberos_derive_salting_principal_direct(context, ccache, enctypes, service); SAFE_FREE(service); } if (asprintf(&service, "host/%s.%s", global_myname(), lp_realm()) != -1) { strlower_m(service); - kerberos_derive_salting_principal(context, ccache, enctypes, service); + kerberos_derive_salting_principal_direct(context, ccache, enctypes, service); SAFE_FREE(service); } name_to_fqdn(my_fqdn, global_myname()); if (asprintf(&service, "cifs/%s", my_fqdn) != -1) { strlower_m(service); - kerberos_derive_salting_principal(context, ccache, enctypes, service); + kerberos_derive_salting_principal_direct(context, ccache, enctypes, service); SAFE_FREE(service); } if (asprintf(&service, "host/%s", my_fqdn) != -1) { strlower_m(service); - kerberos_derive_salting_principal(context, ccache, enctypes, service); + kerberos_derive_salting_principal_direct(context, ccache, enctypes, service); SAFE_FREE(service); } diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c index 90f5a376d6..97374508ab 100644 --- a/source3/libads/kerberos_keytab.c +++ b/source3/libads/kerberos_keytab.c @@ -128,7 +128,7 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc) } /* Guess at how the KDC is salting keys for this principal. */ - kerberos_derive_salting_principal(context, NULL, enctypes, princ_s); + kerberos_derive_salting_principal(princ_s); ret = krb5_parse_name(context, princ_s, &princ); if (ret) { -- cgit From c0e31dd4f53226386a3017c0a4f8401fab102851 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 3 Nov 2004 00:29:09 +0000 Subject: r3495: Fix the build (recent kerberos-changes). Guenther (This used to be commit c7eab285d967345510a15e83bce508edb8e06e99) --- source3/libads/kerberos.c | 6 ++++-- source3/libads/kerberos_verify.c | 1 - 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 32f5951c9f..a38f3c35b1 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -635,7 +635,7 @@ static void kerberos_derive_salting_principal_direct(krb5_context context, Wrapper function for the above. ************************************************************************/ -void kerberos_derive_salting_principal(char *service_principal) +BOOL kerberos_derive_salting_principal(char *service_principal) { krb5_context context = NULL; krb5_enctype *enctypes = NULL; @@ -646,7 +646,7 @@ void kerberos_derive_salting_principal(char *service_principal) if ((ret = krb5_init_context(&context)) != 0) { DEBUG(1,("kerberos_derive_cifs_salting_principals: krb5_init_context failed. %s\n", error_message(ret))); - return; + return False; } if ((ret = get_kerberos_allowed_etypes(context, &enctypes)) != 0) { DEBUG(1,("kerberos_derive_cifs_salting_principals: get_kerberos_allowed_etypes failed. %s\n", @@ -672,6 +672,8 @@ void kerberos_derive_salting_principal(char *service_principal) if (context) { krb5_free_context(context); } + + return ret ? False : True; } /************************************************************************ diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 8524fc5d05..848bd61acc 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -231,7 +231,6 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, char *host_princ_s = NULL; BOOL got_replay_mutex = False; - fstring myname; BOOL auth_ok = False; ZERO_STRUCT(packet); -- cgit From 5ee08e89bfc695663f45952c5b7f2fac733ed064 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 3 Nov 2004 02:18:51 +0000 Subject: r3502: Tidy up debugging in kerberos_keytab code. Jeremy. (This used to be commit 82651c1b1704d90ca52be1463ee871801c607d3b) --- source3/libads/kerberos_keytab.c | 80 ++++++++++++++++++++++++---------------- 1 file changed, 48 insertions(+), 32 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c index 97374508ab..ec6a8c5078 100644 --- a/source3/libads/kerberos_keytab.c +++ b/source3/libads/kerberos_keytab.c @@ -148,7 +148,7 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc) if (ret != KRB5_KT_END && ret != ENOENT ) { DEBUG(3,("ads_keytab_add_entry: Will try to delete old keytab entries\n")); while(!krb5_kt_next_entry(context, keytab, &kt_entry, &cursor)) { - BOOL compare_ok = False; + BOOL compare_name_ok = False; ret = krb5_unparse_name(context, kt_entry.principal, &ktprinc); if (ret) { @@ -166,43 +166,59 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc) */ #ifdef HAVE_KRB5_KT_COMPARE - compare_ok = ((krb5_kt_compare(context, &kt_entry, princ, 0, 0) == True) && (kt_entry.vno != kvno - 1)); + compare_name_ok = (krb5_kt_compare(context, &kt_entry, princ, 0, 0) == True); #else - compare_ok = ((strcmp(ktprinc, princ_s) == 0) && (kt_entry.vno != kvno - 1)); + compare_name_ok = (strcmp(ktprinc, princ_s) == 0); #endif + + if (!compare_name_ok) { + DEBUG(10,("ads_keytab_add_entry: ignoring keytab entry principal %s, kvno = %d\n", + ktprinc, kt_entry.vno)); + } + krb5_free_unparsed_name(context, ktprinc); ktprinc = NULL; - if (compare_ok) { - DEBUG(3,("ads_keytab_add_entry: Found old entry for principal: %s (kvno %d) - trying to remove it.\n", - princ_s, kt_entry.vno)); - ret = krb5_kt_end_seq_get(context, keytab, &cursor); - ZERO_STRUCT(cursor); - if (ret) { - DEBUG(1,("ads_keytab_add_entry: krb5_kt_end_seq_get() failed (%s)\n", - error_message(ret))); - goto out; - } - ret = krb5_kt_remove_entry(context, keytab, &kt_entry); - if (ret) { - DEBUG(1,("ads_keytab_add_entry: krb5_kt_remove_entry failed (%s)\n", - error_message(ret))); - goto out; - } - ret = krb5_kt_start_seq_get(context, keytab, &cursor); - if (ret) { - DEBUG(1,("ads_keytab_add_entry: krb5_kt_start_seq failed (%s)\n", - error_message(ret))); - goto out; - } - ret = smb_krb5_kt_free_entry(context, &kt_entry); - ZERO_STRUCT(kt_entry); - if (ret) { - DEBUG(1,("ads_keytab_add_entry: krb5_kt_remove_entry failed (%s)\n", - error_message(ret))); - goto out; + if (compare_name_ok) { + if (kt_entry.vno == kvno - 1) { + DEBUG(5,("ads_keytab_add_entry: Saving previous (kvno %d) entry for principal: %s.\n", + kvno - 1, princ_s)); + } else { + + DEBUG(5,("ads_keytab_add_entry: Found old entry for principal: %s (kvno %d) - trying to remove it.\n", + princ_s, kt_entry.vno)); + ret = krb5_kt_end_seq_get(context, keytab, &cursor); + ZERO_STRUCT(cursor); + if (ret) { + DEBUG(1,("ads_keytab_add_entry: krb5_kt_end_seq_get() failed (%s)\n", + error_message(ret))); + goto out; + } + ret = krb5_kt_remove_entry(context, keytab, &kt_entry); + if (ret) { + DEBUG(1,("ads_keytab_add_entry: krb5_kt_remove_entry failed (%s)\n", + error_message(ret))); + goto out; + } + + DEBUG(5,("ads_keytab_add_entry: removed old entry for principal: %s (kvno %d).\n", + princ_s, kt_entry.vno)); + + ret = krb5_kt_start_seq_get(context, keytab, &cursor); + if (ret) { + DEBUG(1,("ads_keytab_add_entry: krb5_kt_start_seq failed (%s)\n", + error_message(ret))); + goto out; + } + ret = smb_krb5_kt_free_entry(context, &kt_entry); + ZERO_STRUCT(kt_entry); + if (ret) { + DEBUG(1,("ads_keytab_add_entry: krb5_kt_remove_entry failed (%s)\n", + error_message(ret))); + goto out; + } + continue; } - continue; } /* Not a match, just free this entry and continue. */ -- cgit From d4a46dec34c0282500d80f20fa9c4f2a10edabed Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 5 Nov 2004 23:50:26 +0000 Subject: r3569: Fix for bug #1651, added extra servicePrincipalNames for kerberos interop. Modified the redhat patch some... Jeremy. (This used to be commit 2ae717cd2c876649464f91093e55bed64ac5588d) --- source3/libads/ldap.c | 50 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 6 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 749274298f..b2ae5aeb94 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1228,11 +1228,11 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n ADS_STATUS ret; TALLOC_CTX *ctx; LDAPMessage *res = NULL; - char *host_spn, *host_upn, *psp1, *psp2; + char *host_spn, *host_upn, *psp1, *psp2, *psp3; ADS_MODLIST mods; fstring my_fqdn; char *dn_string = NULL; - const char *servicePrincipalName[3] = {NULL, NULL, NULL}; + const char *servicePrincipalName[4] = {NULL, NULL, NULL, NULL}; ret = ads_find_machine_acct(ads, (void **)&res, machine_name); if (!ADS_ERR_OK(ret) || ads_count_replies(ads, res) != 1) { @@ -1251,6 +1251,8 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n } name_to_fqdn(my_fqdn, machine_name); + strlower_m(my_fqdn); + if (!(host_spn = talloc_asprintf(ctx, "HOST/%s", my_fqdn))) { talloc_destroy(ctx); ads_msgfree(ads, res); @@ -1274,6 +1276,17 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n DEBUG(5,("ads_add_service_principal_name: INFO: Adding %s to host %s\n", psp2, machine_name)); servicePrincipalName[1] = psp2; + /* Add another principal in case the realm != the DNS domain, so that + * the KDC doesn't send "server principal unknown" errors to clients + * which use the DNS name in determining service principal names. */ + psp3 = talloc_asprintf(ctx, "%s/%s", spn, my_fqdn); + strupper_m(psp3); + strlower_m(&psp3[strlen(spn)]); + if (strcmp(psp2, psp3) != 0) { + DEBUG(5,("ads_add_service_principal_name: INFO: Adding %s to host %s\n", psp3, machine_name)); + servicePrincipalName[2] = psp3; + } + if (!(mods = ads_init_mods(ctx))) { talloc_destroy(ctx); ads_msgfree(ads, res); @@ -1325,12 +1338,13 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *machine_name ADS_MODLIST mods; const char *objectClass[] = {"top", "person", "organizationalPerson", "user", "computer", NULL}; - const char *servicePrincipalName[5] = {NULL, NULL, NULL, NULL, NULL}; - char *psp, *psp2; + const char *servicePrincipalName[7] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL}; + char *psp, *psp2, *psp3, *psp4; unsigned acct_control; unsigned exists=0; fstring my_fqdn; LDAPMessage *res = NULL; + int i, next_spn; if (!(ctx = talloc_init("ads_add_machine_acct"))) return ADS_ERROR(LDAP_NO_MEMORY); @@ -1384,6 +1398,30 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *machine_name strlower_m(&psp2[5]); servicePrincipalName[3] = psp2; + /* Ensure servicePrincipalName[4] and [5] are unique. */ + strlower_m(my_fqdn); + psp3 = talloc_asprintf(ctx, "CIFS/%s", my_fqdn); + strlower_m(&psp3[5]); + + next_spn = 4; + for (i = 0; i < next_spn; i++) { + if (strequal(servicePrincipalName[i], psp3)) + break; + } + if (i == next_spn) { + servicePrincipalName[next_spn++] = psp3; + } + + psp4 = talloc_asprintf(ctx, "HOST/%s", my_fqdn); + strlower_m(&psp4[5]); + for (i = 0; i < next_spn; i++) { + if (strequal(servicePrincipalName[i], psp3)) + break; + } + if (i == next_spn) { + servicePrincipalName[next_spn++] = psp4; + } + if (!(samAccountName = talloc_asprintf(ctx, "%s$", machine_name))) { goto done; } @@ -1683,14 +1721,14 @@ ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *machine_name, status = ads_add_machine_acct(ads, machine, account_type, org_unit); if (!ADS_ERR_OK(status)) { - DEBUG(0, ("ads_add_machine_acct (%s): %s\n", machine, ads_errstr(status))); + DEBUG(0, ("ads_join_realm: ads_add_machine_acct failed (%s): %s\n", machine, ads_errstr(status))); SAFE_FREE(machine); return status; } status = ads_find_machine_acct(ads, (void **)&res, machine); if (!ADS_ERR_OK(status)) { - DEBUG(0, ("Host account test failed for machine %s\n", machine)); + DEBUG(0, ("ads_join_realm: Host account test failed for machine %s\n", machine)); SAFE_FREE(machine); return status; } -- cgit From a13b603b79e170683b6b5b339d3494d32a9eaf39 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 12 Nov 2004 23:13:03 +0000 Subject: r3711: Fix KRB5_SETPW-defines, no change in behaviour. A value of '2' is due to an expired internet draft, while 0xff80 comes from RFC3244. See Bugzilla #1661 for details. Thanks to Luke Mewburn for his research. Guenther (This used to be commit 3906c1623fb3823612347a0533ad49d7dfbe1b99) --- source3/libads/krb5_setpw.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index a45bf23610..9582574851 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -25,10 +25,8 @@ #define DEFAULT_KPASSWD_PORT 464 #define KRB5_KPASSWD_VERS_CHANGEPW 1 -#ifndef KRB5_KPASSWD_VERS_SETPW -#define KRB5_KPASSWD_VERS_SETPW 2 -#endif -#define KRB5_KPASSWD_VERS_SETPW_MS 0xff80 +#define KRB5_KPASSWD_VERS_SETPW 0xff80 +#define KRB5_KPASSWD_VERS_SETPW_ALT 2 #define KRB5_KPASSWD_ACCESSDENIED 5 #define KRB5_KPASSWD_BAD_VERSION 6 #define KRB5_KPASSWD_INITIAL_FLAG_NEEDED 7 @@ -140,7 +138,7 @@ static krb5_error_code build_kpasswd_request(uint16 pversion, if (pversion == KRB5_KPASSWD_VERS_CHANGEPW) setpw = data_blob(passwd, strlen(passwd)); else if (pversion == KRB5_KPASSWD_VERS_SETPW || - pversion == KRB5_KPASSWD_VERS_SETPW_MS) + pversion == KRB5_KPASSWD_VERS_SETPW_ALT) setpw = encode_krb5_setpw(princ, passwd); else return EINVAL; @@ -252,7 +250,7 @@ static krb5_error_code parse_setpw_reply(krb5_context context, /* FIXME: According to standard there is only one type of reply */ if (vnum != KRB5_KPASSWD_VERS_SETPW && - vnum != KRB5_KPASSWD_VERS_SETPW_MS && + vnum != KRB5_KPASSWD_VERS_SETPW_ALT && vnum != KRB5_KPASSWD_VERS_CHANGEPW) { DEBUG(1,("Bad vnum (%d) from kpasswd server\n", vnum)); return KRB5KDC_ERR_BAD_PVNO; @@ -557,7 +555,7 @@ ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ, /* we might have to call krb5_free_creds(...) from now on ... */ aret = do_krb5_kpasswd_request(context, kdc_host, - KRB5_KPASSWD_VERS_SETPW_MS, + KRB5_KPASSWD_VERS_SETPW, credsp, princ, newpw); krb5_free_creds(context, credsp); -- cgit From aad0bc6c3782099d7eb070450863663ce5d77050 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 15 Nov 2004 18:57:22 +0000 Subject: r3764: Ensure on failure that *res is always NULL. Check for malloc fail. Fixes for bug #2036. Jeremy. (This used to be commit b815247747214ba413c054746e9732d5f2b10535) --- source3/libads/ldap.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index b2ae5aeb94..252cd718c8 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -456,8 +456,6 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, controls[1] = &PagedResults; controls[2] = NULL; - *res = NULL; - /* we need to disable referrals as the openldap libs don't handle them and paged results at the same time. Using them together results in the result record containing the server @@ -533,6 +531,7 @@ ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, int count = 0; ADS_STATUS status; + *res = NULL; status = ads_do_paged_search(ads, bind_path, scope, expr, attrs, res, &count, &cookie); @@ -623,6 +622,7 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, char *utf8_expr, *utf8_path, **search_attrs = NULL; TALLOC_CTX *ctx; + *res = NULL; if (!(ctx = talloc_init("ads_do_search"))) { DEBUG(1,("ads_do_search: talloc_init() failed!")); return ADS_ERROR(LDAP_NO_MEMORY); @@ -653,7 +653,6 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, timeout.tv_sec = ADS_SEARCH_TIMEOUT; timeout.tv_usec = 0; - *res = NULL; /* see the note in ads_do_paged_search - we *must* disable referrals */ ldap_set_option(ads->ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF); @@ -764,6 +763,8 @@ ADS_STATUS ads_find_machine_acct(ADS_STRUCT *ads, void **res, const char *machin char *expr; const char *attrs[] = {"*", "nTSecurityDescriptor", NULL}; + *res = NULL; + /* the easiest way to find a machine account anywhere in the tree is to look for hostname$ */ if (asprintf(&expr, "(samAccountName=%s$)", machine) == -1) { @@ -2494,6 +2495,10 @@ ADS_STATUS ads_workgroup_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char * asprintf(&expr, "(&(objectclass=computer)(dnshostname=%s.%s))", ads->config.ldap_server_name, ads->config.realm); + if (expr == NULL) { + ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + } + rc = ads_search(ads, &res, expr, attrs); free(expr); -- cgit From 6ab46e3fd2cb2394bb00b45ded0e372d0992284a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 17 Nov 2004 01:43:36 +0000 Subject: r3796: Patch from Jay Fenlason . Don't free static buffers. Jeremy. (This used to be commit 53acf222a86a1420abbba08a2cde27a86debe403) --- source3/libads/util.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/util.c b/source3/libads/util.c index f5b8873538..4a4d90d7fb 100644 --- a/source3/libads/util.c +++ b/source3/libads/util.c @@ -62,7 +62,6 @@ ADS_STATUS ads_change_trust_account_password(ADS_STRUCT *ads, char *host_princip failed: SAFE_FREE(service_principal); SAFE_FREE(password); - SAFE_FREE(new_password); return ret; } #endif -- cgit From 0bd9bc6ecae10fa21e4315ea9f20b52fc5883f30 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 18 Nov 2004 11:43:14 +0000 Subject: r3841: Time out in ads search queries. Even AD servers can hang. Volker (This used to be commit fc454c8ef6321fba9efa42a704c8e8c707361af3) --- source3/libads/ldap.c | 51 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 7 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 252cd718c8..7bddc0e9b5 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -67,6 +67,40 @@ static void gotalarm_sig(void) return ldp; } +static int ldap_search_with_timeout(LDAP *ld, + LDAP_CONST char *base, + int scope, + LDAP_CONST char *filter, + char **attrs, + int attrsonly, + LDAPControl **sctrls, + LDAPControl **cctrls, + struct timeval *timeout, + int sizelimit, + LDAPMessage **res ) +{ + int result; + + /* Setup timeout */ + gotalarm = 0; + CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig); + alarm(lp_ldap_timeout()); + /* End setup timeout. */ + + result = ldap_search_ext_s(ld, base, scope, filter, attrs, + attrsonly, sctrls, cctrls, timeout, + sizelimit, res); + + /* Teardown timeout. */ + CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN); + alarm(0); + + if (gotalarm != 0) + return LDAP_TIMELIMIT_EXCEEDED; + + return result; +} + /* try a connection to a given ldap server, returning True and setting the servers IP in the ads struct if successful @@ -466,15 +500,17 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, */ ldap_set_option(ads->ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF); - rc = ldap_search_ext_s(ads->ld, utf8_path, scope, utf8_expr, - search_attrs, 0, controls, - NULL, NULL, LDAP_NO_LIMIT, (LDAPMessage **)res); + rc = ldap_search_with_timeout(ads->ld, utf8_path, scope, utf8_expr, + search_attrs, 0, controls, + NULL, NULL, LDAP_NO_LIMIT, + (LDAPMessage **)res); ber_free(cookie_be, 1); ber_bvfree(cookie_bv); if (rc) { - DEBUG(3,("ldap_search_ext_s(%s) -> %s\n", expr, ldap_err2string(rc))); + DEBUG(3,("ldap_search_with_timeout(%s) -> %s\n", expr, + ldap_err2string(rc))); goto done; } @@ -657,9 +693,10 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, /* see the note in ads_do_paged_search - we *must* disable referrals */ ldap_set_option(ads->ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF); - rc = ldap_search_ext_s(ads->ld, utf8_path, scope, utf8_expr, - search_attrs, 0, NULL, NULL, - &timeout, LDAP_NO_LIMIT, (LDAPMessage **)res); + rc = ldap_search_with_timeout(ads->ld, utf8_path, scope, utf8_expr, + search_attrs, 0, NULL, NULL, + &timeout, LDAP_NO_LIMIT, + (LDAPMessage **)res); if (rc == LDAP_SIZELIMIT_EXCEEDED) { DEBUG(3,("Warning! sizelimit exceeded in ldap. Truncating.\n")); -- cgit From bd4391033113abc592b1a29b53eaa6d7415bb28e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 30 Nov 2004 22:57:41 +0000 Subject: r4023: Code tidyup to fix bug #2098. Jeremy. (This used to be commit ebaf21e3e289d3570f20b22e00555eaebe060063) --- source3/libads/ads_status.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_status.c b/source3/libads/ads_status.c index 463f647f9c..79e07a9b00 100644 --- a/source3/libads/ads_status.c +++ b/source3/libads/ads_status.c @@ -96,11 +96,9 @@ NTSTATUS ads_ntstatus(ADS_STATUS status) */ const char *ads_errstr(ADS_STATUS status) { - uint32 msg_ctx; static char *ret; SAFE_FREE(ret); - msg_ctx = 0; switch (status.error_type) { case ENUM_ADS_ERROR_SYSTEM: @@ -116,7 +114,10 @@ const char *ads_errstr(ADS_STATUS status) #ifdef HAVE_GSSAPI case ENUM_ADS_ERROR_GSS: { + uint32 msg_ctx; uint32 minor; + + msg_ctx = 0; gss_buffer_desc msg1, msg2; msg1.value = NULL; -- cgit From acf9d61421faa6c0055d57fdee7db300dc5431aa Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 7 Dec 2004 18:25:53 +0000 Subject: r4088: Get medieval on our ass about malloc.... :-). Take control of all our allocation functions so we can funnel through some well known functions. Should help greatly with malloc checking. HEAD patch to follow. Jeremy. (This used to be commit 620f2e608f70ba92f032720c031283d295c5c06a) --- source3/libads/ads_struct.c | 12 ++++---- source3/libads/authdata.c | 34 ++++++++--------------- source3/libads/kerberos_keytab.c | 2 +- source3/libads/kerberos_verify.c | 2 +- source3/libads/krb5_setpw.c | 8 +++--- source3/libads/ldap.c | 60 ++++++++++++++++++++-------------------- source3/libads/ldap_printer.c | 5 ++-- source3/libads/ldap_utils.c | 2 +- source3/libads/sasl.c | 2 +- 9 files changed, 58 insertions(+), 69 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index 92f37093f4..e8546f86f5 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -31,7 +31,7 @@ char *ads_build_path(const char *realm, const char *sep, const char *field, int char *ret; int len; - r = strdup(realm); + r = SMB_STRDUP(realm); if (!r || !*r) return r; @@ -42,7 +42,7 @@ char *ads_build_path(const char *realm, const char *sep, const char *field, int len = (numbits+1)*(strlen(field)+1) + strlen(r) + 1; - ret = malloc(len); + ret = SMB_MALLOC(len); if (!ret) return NULL; @@ -87,12 +87,12 @@ ADS_STRUCT *ads_init(const char *realm, { ADS_STRUCT *ads; - ads = (ADS_STRUCT *)smb_xmalloc(sizeof(*ads)); + ads = SMB_XMALLOC_P(ADS_STRUCT); ZERO_STRUCTP(ads); - ads->server.realm = realm? strdup(realm) : NULL; - ads->server.workgroup = workgroup ? strdup(workgroup) : NULL; - ads->server.ldap_server = ldap_server? strdup(ldap_server) : NULL; + ads->server.realm = realm? SMB_STRDUP(realm) : NULL; + ads->server.workgroup = workgroup ? SMB_STRDUP(workgroup) : NULL; + ads->server.ldap_server = ldap_server? SMB_STRDUP(ldap_server) : NULL; /* we need to know if this is a foreign realm */ if (realm && *realm && !strequal(lp_realm(), realm)) { diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c index 29170af377..ccaf82124c 100644 --- a/source3/libads/authdata.c +++ b/source3/libads/authdata.c @@ -59,7 +59,7 @@ static BOOL pac_io_unknown_type_10(const char *desc, UNKNOWN_TYPE_10 *type_10, return False; if (UNMARSHALLING(ps) && type_10->len) { - type_10->username = (uint16 *) prs_alloc_mem(ps, type_10->len); + type_10->username = PRS_ALLOC_MEM(ps, uint16, type_10->len); if (!type_10->username) { DEBUG(3, ("No memory available\n")); return False; @@ -85,8 +85,7 @@ static BOOL pac_io_krb_sids(const char *desc, KRB_SID_AND_ATTRS *sid_and_attr, depth++; if (UNMARSHALLING(ps)) { - sid_and_attr->sid = - (DOM_SID2 * ) prs_alloc_mem(ps, sizeof(DOM_SID2)); + sid_and_attr->sid = PRS_ALLOC_MEM(ps, DOM_SID2, 1); if (!sid_and_attr->sid) { DEBUG(3, ("No memory available\n")); return False; @@ -135,8 +134,7 @@ static BOOL pac_io_krb_sid_and_attr_array(const char *desc, return False; if (UNMARSHALLING(ps)) { - array->krb_sid_and_attrs = (KRB_SID_AND_ATTRS *) - prs_alloc_mem(ps, sizeof(KRB_SID_AND_ATTRS) * num); + array->krb_sid_and_attrs = PRS_ALLOC_MEM(ps, KRB_SID_AND_ATTRS, num); if (!array->krb_sid_and_attrs) { DEBUG(3, ("No memory available\n")); return False; @@ -199,8 +197,7 @@ static BOOL pac_io_group_membership_array(const char *desc, return False; if (UNMARSHALLING(ps)) { - array->group_membership = (GROUP_MEMBERSHIP *) - prs_alloc_mem(ps, sizeof(GROUP_MEMBERSHIP) * num); + array->group_membership = PRS_ALLOC_MEM(ps, GROUP_MEMBERSHIP, num); if (!array->group_membership) { DEBUG(3, ("No memory available\n")); return False; @@ -423,7 +420,7 @@ static BOOL pac_io_pac_signature_data(const char *desc, if (!prs_uint32("type", ps, depth, &data->type)) return False; if (UNMARSHALLING(ps)) { - data->signature = (unsigned char *)prs_alloc_mem(ps, siglen); + data->signature = PRS_ALLOC_MEM(ps, unsigned char, siglen); if (!data->signature) { DEBUG(3, ("No memory available\n")); return False; @@ -454,8 +451,7 @@ static BOOL pac_io_pac_info_hdr_ctr(const char *desc, PAC_INFO_HDR *hdr, } if (UNMARSHALLING(ps) && hdr->size > 0) { - hdr->ctr = (PAC_INFO_CTR *) - prs_alloc_mem(ps, sizeof(PAC_INFO_CTR)); + hdr->ctr = PRS_ALLOC_MEM(ps, PAC_INFO_CTR, 1); if (!hdr->ctr) { DEBUG(3, ("No memory available\n")); return False; @@ -466,8 +462,7 @@ static BOOL pac_io_pac_info_hdr_ctr(const char *desc, PAC_INFO_HDR *hdr, case PAC_TYPE_LOGON_INFO: DEBUG(5, ("PAC_TYPE_LOGON_INFO\n")); if (UNMARSHALLING(ps)) - hdr->ctr->pac.logon_info = (PAC_LOGON_INFO *) - prs_alloc_mem(ps, sizeof(PAC_LOGON_INFO)); + hdr->ctr->pac.logon_info = PRS_ALLOC_MEM(ps, PAC_LOGON_INFO, 1); if (!hdr->ctr->pac.logon_info) { DEBUG(3, ("No memory available\n")); return False; @@ -480,8 +475,7 @@ static BOOL pac_io_pac_info_hdr_ctr(const char *desc, PAC_INFO_HDR *hdr, case PAC_TYPE_SERVER_CHECKSUM: DEBUG(5, ("PAC_TYPE_SERVER_CHECKSUM\n")); if (UNMARSHALLING(ps)) - hdr->ctr->pac.srv_cksum = (PAC_SIGNATURE_DATA *) - prs_alloc_mem(ps, sizeof(PAC_SIGNATURE_DATA)); + hdr->ctr->pac.srv_cksum = PRS_ALLOC_MEM(ps, PAC_SIGNATURE_DATA, 1); if (!hdr->ctr->pac.srv_cksum) { DEBUG(3, ("No memory available\n")); return False; @@ -494,8 +488,7 @@ static BOOL pac_io_pac_info_hdr_ctr(const char *desc, PAC_INFO_HDR *hdr, case PAC_TYPE_PRIVSVR_CHECKSUM: DEBUG(5, ("PAC_TYPE_PRIVSVR_CHECKSUM\n")); if (UNMARSHALLING(ps)) - hdr->ctr->pac.privsrv_cksum = (PAC_SIGNATURE_DATA *) - prs_alloc_mem(ps, sizeof(PAC_SIGNATURE_DATA)); + hdr->ctr->pac.privsrv_cksum = PRS_ALLOC_MEM(ps, PAC_SIGNATURE_DATA, 1); if (!hdr->ctr->pac.privsrv_cksum) { DEBUG(3, ("No memory available\n")); return False; @@ -509,8 +502,7 @@ static BOOL pac_io_pac_info_hdr_ctr(const char *desc, PAC_INFO_HDR *hdr, case PAC_TYPE_UNKNOWN_10: DEBUG(5, ("PAC_TYPE_UNKNOWN_10\n")); if (UNMARSHALLING(ps)) - hdr->ctr->pac.type_10 = (UNKNOWN_TYPE_10 *) - prs_alloc_mem(ps, sizeof(UNKNOWN_TYPE_10)); + hdr->ctr->pac.type_10 = PRS_ALLOC_MEM(ps, UNKNOWN_TYPE_10, 1); if (!hdr->ctr->pac.type_10) { DEBUG(3, ("No memory available\n")); return False; @@ -571,9 +563,7 @@ static BOOL pac_io_pac_data(const char *desc, PAC_DATA *data, return False; if (UNMARSHALLING(ps) && data->num_buffers > 0) { - if ((data->pac_info_hdr_ptr = (PAC_INFO_HDR *) - prs_alloc_mem(ps, sizeof(PAC_INFO_HDR) * - data->num_buffers)) == NULL) { + if ((data->pac_info_hdr_ptr = PRS_ALLOC_MEM(ps, PAC_INFO_HDR, data->num_buffers)) == NULL) { return False; } } @@ -606,7 +596,7 @@ PAC_DATA *decode_pac_data(DATA_BLOB *auth_data, TALLOC_CTX *ctx) data_blob_free(&pac_data_blob); - pac_data = (PAC_DATA *) talloc_zero(ctx, sizeof(PAC_DATA)); + pac_data = TALLOC_ZERO_P(ctx, PAC_DATA); pac_io_pac_data("pac data", pac_data, &ps, 0); prs_mem_free(&ps); diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c index ec6a8c5078..8475f70ec4 100644 --- a/source3/libads/kerberos_keytab.c +++ b/source3/libads/kerberos_keytab.c @@ -546,7 +546,7 @@ int ads_keytab_create_default(ADS_STRUCT *ads) if (!found) { goto done; } - oldEntries = (char **) malloc(found * sizeof(char *)); + oldEntries = SMB_MALLOC_ARRAY(char *, found ); if (!oldEntries) { DEBUG(1,("ads_keytab_create_default: Failed to allocate space to store the old keytab entries (malloc failed?).\n")); ret = -1; diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 848bd61acc..f7cbe8674b 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -174,7 +174,7 @@ static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context au for (i=0;enctypes[i];i++) { krb5_keyblock *key = NULL; - if (!(key = (krb5_keyblock *)malloc(sizeof(*key)))) { + if (!(key = SMB_MALLOC_P(krb5_keyblock))) { goto out; } diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 9582574851..dadce2593c 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -54,7 +54,7 @@ static DATA_BLOB encode_krb5_setpw(const char *principal, const char *password) DATA_BLOB ret; - princ = strdup(principal); + princ = SMB_STRDUP(principal); if ((c = strchr_m(princ, '/')) == NULL) { c = princ; @@ -156,7 +156,7 @@ static krb5_error_code build_kpasswd_request(uint16 pversion, return ret; } - packet->data = (char *)malloc(ap_req->length + cipherpw.length + 6); + packet->data = (char *)SMB_MALLOC(ap_req->length + cipherpw.length + 6); if (!packet->data) return -1; @@ -407,7 +407,7 @@ static ADS_STATUS do_krb5_kpasswd_request(krb5_context context, free(chpw_req.data); chpw_rep.length = 1500; - chpw_rep.data = (char *) malloc(chpw_rep.length); + chpw_rep.data = (char *) SMB_MALLOC(chpw_rep.length); if (!chpw_rep.data) { close(sock); free(ap_req.data); @@ -631,7 +631,7 @@ static ADS_STATUS ads_krb5_chg_password(const char *kdc_host, /* We have to obtain an INITIAL changepw ticket for changing password */ asprintf(&chpw_princ, "kadmin/changepw@%s", (char *) krb5_princ_realm(context, princ)); - password = strdup(oldpw); + password = SMB_STRDUP(oldpw); ret = krb5_get_init_creds_password(context, &creds, princ, password, kerb_prompter, NULL, 0, chpw_princ, &opts); diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 7bddc0e9b5..c18e253f7b 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -119,7 +119,7 @@ static BOOL ads_try_connect(ADS_STRUCT *ads, const char *server, unsigned port) DEBUG(5,("ads_try_connect: trying ldap server '%s' port %u\n", server, port)); /* this copes with inet_ntoa brokenness */ - srv = strdup(server); + srv = SMB_STRDUP(server); ads->ld = ldap_open_with_timeout(srv, port, lp_ldap_timeout()); if (!ads->ld) { @@ -296,11 +296,11 @@ got_connection: } if (!ads->auth.realm) { - ads->auth.realm = strdup(ads->config.realm); + ads->auth.realm = SMB_STRDUP(ads->config.realm); } if (!ads->auth.kdc_server) { - ads->auth.kdc_server = strdup(inet_ntoa(ads->ldap_ip)); + ads->auth.kdc_server = SMB_STRDUP(inet_ntoa(ads->ldap_ip)); } #if KRB5_DNS_HACK @@ -338,13 +338,13 @@ static struct berval *dup_berval(TALLOC_CTX *ctx, const struct berval *in_val) if (!in_val) return NULL; - value = talloc_zero(ctx, sizeof(struct berval)); + value = TALLOC_ZERO_P(ctx, struct berval); if (value == NULL) return NULL; if (in_val->bv_len == 0) return value; value->bv_len = in_val->bv_len; - value->bv_val = talloc_memdup(ctx, in_val->bv_val, in_val->bv_len); + value->bv_val = TALLOC_MEMDUP(ctx, in_val->bv_val, in_val->bv_len); return value; } @@ -358,9 +358,9 @@ static struct berval **ads_dup_values(TALLOC_CTX *ctx, int i; if (!in_vals) return NULL; - for (i=0; in_vals[i]; i++); /* count values */ - values = (struct berval **) talloc_zero(ctx, - (i+1)*sizeof(struct berval *)); + for (i=0; in_vals[i]; i++) + ; /* count values */ + values = TALLOC_ZERO_ARRAY(ctx, struct berval *, i+1); if (!values) return NULL; for (i=0; in_vals[i]; i++) { @@ -378,8 +378,9 @@ static char **ads_push_strvals(TALLOC_CTX *ctx, const char **in_vals) int i; if (!in_vals) return NULL; - for (i=0; in_vals[i]; i++); /* count values */ - values = (char ** ) talloc_zero(ctx, (i+1)*sizeof(char *)); + for (i=0; in_vals[i]; i++) + ; /* count values */ + values = TALLOC_ZERO_ARRAY(ctx, char *, i+1); if (!values) return NULL; for (i=0; in_vals[i]; i++) { @@ -397,8 +398,9 @@ static char **ads_pull_strvals(TALLOC_CTX *ctx, const char **in_vals) int i; if (!in_vals) return NULL; - for (i=0; in_vals[i]; i++); /* count values */ - values = (char **) talloc_zero(ctx, (i+1)*sizeof(char *)); + for (i=0; in_vals[i]; i++) + ; /* count values */ + values = TALLOC_ZERO_ARRAY(ctx, char *, i+1); if (!values) return NULL; for (i=0; in_vals[i]; i++) { @@ -824,8 +826,7 @@ ADS_MODLIST ads_init_mods(TALLOC_CTX *ctx) #define ADS_MODLIST_ALLOC_SIZE 10 LDAPMod **mods; - if ((mods = (LDAPMod **) talloc_zero(ctx, sizeof(LDAPMod *) * - (ADS_MODLIST_ALLOC_SIZE + 1)))) + if ((mods = TALLOC_ZERO_ARRAY(ctx, LDAPMod *, ADS_MODLIST_ALLOC_SIZE + 1))) /* -1 is safety to make sure we don't go over the end. need to reset it to NULL before doing ldap modify */ mods[ADS_MODLIST_ALLOC_SIZE] = (LDAPMod *) -1; @@ -861,8 +862,8 @@ static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, for (curmod=0; modlist[curmod] && modlist[curmod] != (LDAPMod *) -1; curmod++); if (modlist[curmod] == (LDAPMod *) -1) { - if (!(modlist = talloc_realloc(ctx, modlist, - (curmod+ADS_MODLIST_ALLOC_SIZE+1)*sizeof(LDAPMod *)))) + if (!(modlist = TALLOC_REALLOC_ARRAY(ctx, modlist, LDAPMod *, + curmod+ADS_MODLIST_ALLOC_SIZE+1))) return ADS_ERROR(LDAP_NO_MEMORY); memset(&modlist[curmod], 0, ADS_MODLIST_ALLOC_SIZE*sizeof(LDAPMod *)); @@ -870,7 +871,7 @@ static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, *mods = modlist; } - if (!(modlist[curmod] = talloc_zero(ctx, sizeof(LDAPMod)))) + if (!(modlist[curmod] = TALLOC_ZERO_P(ctx, LDAPMod))) return ADS_ERROR(LDAP_NO_MEMORY); modlist[curmod]->mod_type = talloc_strdup(ctx, name); if (mod_op & LDAP_MOD_BVALUES) { @@ -1046,11 +1047,11 @@ char *ads_ou_string(ADS_STRUCT *ads, const char *org_unit) ret = ads_default_ou_string(ads, WELL_KNOWN_GUID_COMPUTERS); /* samba4 might not yet respond to a wellknownobject-query */ - return ret ? ret : strdup("cn=Computers"); + return ret ? ret : SMB_STRDUP("cn=Computers"); } if (strequal(org_unit, "Computers")) { - return strdup("cn=Computers"); + return SMB_STRDUP("cn=Computers"); } return ads_build_path(org_unit, "\\/", "ou=", 1); @@ -1107,7 +1108,7 @@ char *ads_default_ou_string(ADS_STRUCT *ads, const char *wknguid) for (i=1; i < new_ln; i++) { char *s; asprintf(&s, "%s,%s", ret, wkn_dn_exp[i]); - ret = strdup(s); + ret = SMB_STRDUP(s); free(s); } @@ -1741,7 +1742,7 @@ ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *machine_name, char *machine; /* machine name must be lowercase */ - machine = strdup(machine_name); + machine = SMB_STRDUP(machine_name); strlower_m(machine); /* @@ -1791,7 +1792,7 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) int rc; /* hostname must be lowercase */ - host = strdup(hostname); + host = SMB_STRDUP(hostname); strlower_m(host); status = ads_find_machine_acct(ads, &res, host); @@ -1915,7 +1916,7 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) if (!(mods = ads_init_mods(ctx))) return ADS_ERROR(LDAP_NO_MEMORY); bval.bv_len = prs_offset(&ps_wire); - bval.bv_val = talloc(ctx, bval.bv_len); + bval.bv_val = TALLOC(ctx, bval.bv_len); if (!bval.bv_val) { ret = ADS_ERROR(LDAP_NO_MEMORY); goto ads_set_sd_error; @@ -2015,7 +2016,7 @@ char **ads_pull_strings(ADS_STRUCT *ads, *num_values = ldap_count_values(values); - ret = talloc(mem_ctx, sizeof(char *) * (*num_values+1)); + ret = TALLOC_ARRAY(mem_ctx, char *, *num_values + 1); if (!ret) { ldap_value_free(values); return NULL; @@ -2126,9 +2127,8 @@ char **ads_pull_strings_range(ADS_STRUCT *ads, return NULL; } - strings = talloc_realloc(mem_ctx, current_strings, - sizeof(*current_strings) * - (*num_strings + num_new_strings)); + strings = TALLOC_REALLOC_ARRAY(mem_ctx, current_strings, char *, + *num_strings + num_new_strings); if (strings == NULL) { ldap_memfree(range_attr); @@ -2265,7 +2265,7 @@ int ads_pull_sids(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, for (i=0; values[i]; i++) /* nop */ ; - (*sids) = talloc(mem_ctx, sizeof(DOM_SID) * i); + (*sids) = TALLOC_ARRAY(mem_ctx, DOM_SID, i); if (!(*sids)) { ldap_value_free_len(values); return 0; @@ -2446,7 +2446,7 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads) SAFE_FREE(ads->config.ldap_server_name); - ads->config.ldap_server_name = strdup(p+1); + ads->config.ldap_server_name = SMB_STRDUP(p+1); p = strchr(ads->config.ldap_server_name, '$'); if (!p || p[1] != '@') { talloc_destroy(ctx); @@ -2461,7 +2461,7 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads) SAFE_FREE(ads->config.realm); SAFE_FREE(ads->config.bind_path); - ads->config.realm = strdup(p+2); + ads->config.realm = SMB_STRDUP(p+2); ads->config.bind_path = ads_build_dn(ads->config.realm); DEBUG(3,("got ldap server name %s@%s, using bind path: %s\n", diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index d8e4cefcfa..68e6735891 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -161,10 +161,9 @@ static BOOL map_multi_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods, }; if (num_vals) { - str_values = talloc(ctx, - (num_vals + 1) * sizeof(smb_ucs2_t *)); + str_values = TALLOC_ARRAY(ctx, char *, num_vals + 1); memset(str_values, '\0', - (num_vals + 1) * sizeof(smb_ucs2_t *)); + (num_vals + 1) * sizeof(char *)); cur_str = (smb_ucs2_t *) value->data_p; for (i=0; i < num_vals; i++) diff --git a/source3/libads/ldap_utils.c b/source3/libads/ldap_utils.c index 991f16c845..03cdd339f0 100644 --- a/source3/libads/ldap_utils.c +++ b/source3/libads/ldap_utils.c @@ -42,7 +42,7 @@ ADS_STATUS ads_do_search_retry(ADS_STRUCT *ads, const char *bind_path, int scope return ADS_ERROR(LDAP_SERVER_DOWN); } - bp = strdup(bind_path); + bp = SMB_STRDUP(bind_path); if (!bp) { return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 8eb2c86bed..97ba9c9286 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -374,7 +374,7 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) gss_release_buffer(&minor_status, &output_token); - output_token.value = malloc(strlen(ads->config.bind_path) + 8); + output_token.value = SMB_MALLOC(strlen(ads->config.bind_path) + 8); p = output_token.value; *p++ = 1; /* no sign & seal selection */ -- cgit From 3c11b0310060bc5143fdc64cb4eb3fbc691eb53d Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sun, 19 Dec 2004 03:23:10 +0000 Subject: r4273: Same fix for r4272 in SAMBA_3_0 branch. (This used to be commit 4f1927acfa6569fc90317d76ed34e5ee088df7c1) --- source3/libads/ads_status.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_status.c b/source3/libads/ads_status.c index 79e07a9b00..536ef766e3 100644 --- a/source3/libads/ads_status.c +++ b/source3/libads/ads_status.c @@ -116,10 +116,10 @@ const char *ads_errstr(ADS_STATUS status) { uint32 msg_ctx; uint32 minor; + gss_buffer_desc msg1, msg2; msg_ctx = 0; - gss_buffer_desc msg1, msg2; msg1.value = NULL; msg2.value = NULL; gss_display_status(&minor, status.err.rc, GSS_C_GSS_CODE, -- cgit From 44bac2bf7b8537a7cd414a883b5c89042c6ad179 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 22 Dec 2004 22:07:04 +0000 Subject: r4334: Fix for bugid #2186 - from Buck Huppmann to prevent uninitialized creds being freed. Jeremy. (This used to be commit c3f9c81a8fcb26f7110f75b3096d5d1eb30aac13) --- source3/libads/kerberos.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index a38f3c35b1..b08e28e0ba 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -320,6 +320,8 @@ static krb5_error_code get_service_ticket(krb5_context ctx, krb5_auth_context auth_context = NULL; krb5_error_code err = 0; + ZERO_STRUCT(creds); + asprintf(&machine_account, "%s$@%s", global_myname(), lp_realm()); if (machine_account == NULL) { goto out; @@ -340,7 +342,6 @@ static krb5_error_code get_service_ticket(krb5_context ctx, ticket to ourselves. */ /* Set up the enctype and client and server principal fields for krb5_get_credentials. */ - memset(&creds, '\0', sizeof(creds)); kerberos_set_creds_enctype(&creds, enctype); if ((err = krb5_cc_get_principal(ctx, ccache, &creds.client))) { -- cgit From 883874c5628f70279ea733e08153b91ea3f83c25 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 23 Dec 2004 18:40:50 +0000 Subject: r4346: Fix cut-and-paste error - bugid #2189. Fixed by Buck Huppmann Jeremy. (This used to be commit 5c22cb082c86088add0db21541a8079c516c9fd9) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index c18e253f7b..8c37a90e73 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1454,7 +1454,7 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *machine_name psp4 = talloc_asprintf(ctx, "HOST/%s", my_fqdn); strlower_m(&psp4[5]); for (i = 0; i < next_spn; i++) { - if (strequal(servicePrincipalName[i], psp3)) + if (strequal(servicePrincipalName[i], psp4)) break; } if (i == next_spn) { -- cgit From d16a5c4381397efa7f4de2d8c7e9299bec492eb8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 11 Jan 2005 02:13:03 +0000 Subject: r4665: Fix inspired by posting from Joe Meadows . Make all LDAP timeouts consistent. Jeremy. (This used to be commit 0f0281c2348b10ffdea744ecade6b2be0814c872) --- source3/libads/ldap.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 8c37a90e73..494bd930e4 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -75,20 +75,24 @@ static int ldap_search_with_timeout(LDAP *ld, int attrsonly, LDAPControl **sctrls, LDAPControl **cctrls, - struct timeval *timeout, int sizelimit, LDAPMessage **res ) { + struct timeval timeout; int result; - /* Setup timeout */ + /* Setup timeout for the ldap_search_ext_s call - local and remote. */ + timeout.tv_sec = lp_ldap_timeout(); + timeout.tv_usec = 0; + + /* Setup alarm timeout.... Do we need both of these ? JRA. */ gotalarm = 0; CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig); alarm(lp_ldap_timeout()); /* End setup timeout. */ result = ldap_search_ext_s(ld, base, scope, filter, attrs, - attrsonly, sctrls, cctrls, timeout, + attrsonly, sctrls, cctrls, &timeout, sizelimit, res); /* Teardown timeout. */ @@ -504,14 +508,14 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, rc = ldap_search_with_timeout(ads->ld, utf8_path, scope, utf8_expr, search_attrs, 0, controls, - NULL, NULL, LDAP_NO_LIMIT, + NULL, LDAP_NO_LIMIT, (LDAPMessage **)res); ber_free(cookie_be, 1); ber_bvfree(cookie_bv); if (rc) { - DEBUG(3,("ldap_search_with_timeout(%s) -> %s\n", expr, + DEBUG(3,("ads_do_paged_search: ldap_search_with_timeout(%s) -> %s\n", expr, ldap_err2string(rc))); goto done; } @@ -655,7 +659,6 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, const char *expr, const char **attrs, void **res) { - struct timeval timeout; int rc; char *utf8_expr, *utf8_path, **search_attrs = NULL; TALLOC_CTX *ctx; @@ -689,15 +692,12 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, } } - timeout.tv_sec = ADS_SEARCH_TIMEOUT; - timeout.tv_usec = 0; - /* see the note in ads_do_paged_search - we *must* disable referrals */ ldap_set_option(ads->ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF); rc = ldap_search_with_timeout(ads->ld, utf8_path, scope, utf8_expr, search_attrs, 0, NULL, NULL, - &timeout, LDAP_NO_LIMIT, + LDAP_NO_LIMIT, (LDAPMessage **)res); if (rc == LDAP_SIZELIMIT_EXCEEDED) { -- cgit From c3ba8b9a53617c75ffbcfa8ef32044cb1691d693 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 14 Jan 2005 19:26:13 +0000 Subject: r4736: small set of merges from rtunk to minimize the diffs (This used to be commit 4b351f2fcc365a7b7f8c22b5139c299aa54c9458) --- source3/libads/kerberos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index b08e28e0ba..4c9997e080 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -3,7 +3,7 @@ kerberos utility library Copyright (C) Andrew Tridgell 2001 Copyright (C) Remus Koos 2001 - Copyright (C) Nalin Dahyabhai 2004. + Copyright (C) Nalin Dahyabhai 2004. Copyright (C) Jeremy Allison 2004. This program is free software; you can redistribute it and/or modify -- cgit From dbf364c9053406d4fc39c560f547545ad1988065 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 21 Jan 2005 01:42:45 +0000 Subject: r4882: Fix for #2255. Debug should have been 10 not 0. Jeremy. (This used to be commit 5557e1409a9a22759ca3bea021d4a662099e683a) --- source3/libads/kerberos_verify.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index f7cbe8674b..d73fc28a29 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -110,7 +110,7 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut ret = krb5_rd_req(context, &auth_context, p_packet, host_princ, keytab, NULL, pp_tkt); krb5_free_principal(context, host_princ); if (ret) { - DEBUG(0, ("krb5_rd_req(%s) failed: %s\n", host_princ_s[i], error_message(ret))); + DEBUG(10, ("krb5_rd_req(%s) failed: %s\n", host_princ_s[i], error_message(ret))); } else { DEBUG(10,("krb5_rd_req succeeded for principal %s\n", host_princ_s[i])); auth_ok = True; -- cgit From 44be949f28774cae4e79704c1c8f5d624f2bd46c Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 4 Feb 2005 00:25:33 +0000 Subject: r5207: patches from Jay Fenlason @ RedHat (scooped from their Fedora packages) (This used to be commit 9019a8436162d3606f6b8584701b0832cf5a7439) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 494bd930e4..c9bba72524 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2526,7 +2526,7 @@ ADS_STATUS ads_workgroup_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char * int i; void *res; const char *attrs[] = {"servicePrincipalName", NULL}; - int num_principals; + size_t num_principals; (*workgroup) = NULL; -- cgit From a309fed583609d19c74c6f3eb63d2113b2a337d3 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 11 Feb 2005 14:31:14 +0000 Subject: r5336: BUG 2329: fix to re-enable winbindd to locate DC's when 'disable netbios = yes' (This used to be commit 75a223f1188ae0041c9e3c748af107d642f73810) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index c9bba72524..6e1b011c37 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -112,7 +112,7 @@ static int ldap_search_with_timeout(LDAP *ld, TODO : add a negative connection cache in here leveraged off of the one found in the rpc code. --jerry */ -static BOOL ads_try_connect(ADS_STRUCT *ads, const char *server, unsigned port) +BOOL ads_try_connect(ADS_STRUCT *ads, const char *server, unsigned port) { char *srv; -- cgit From ce8ad0c3b138dbce01e59810150e120277b98557 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 11 Mar 2005 20:59:16 +0000 Subject: r5759: Patch from Doug VanLeuven to add more case/realm/name permutations to the kerberos keytab. Jeremy. (This used to be commit c687e73f242967cd3a78db66c1dd23349766ebb8) --- source3/libads/kerberos_keytab.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c index 8475f70ec4..f6ed107ee0 100644 --- a/source3/libads/kerberos_keytab.c +++ b/source3/libads/kerberos_keytab.c @@ -440,10 +440,12 @@ int ads_keytab_create_default(ADS_STRUCT *ads) krb5_kt_cursor cursor; krb5_keytab_entry kt_entry; krb5_kvno kvno; - fstring my_fqdn, my_Fqdn, my_name, my_NAME; + fstring my_fqdn, my_Fqdn, my_name, my_NAME, my_host_realm; char *p_fqdn; int i, found = 0; - char **oldEntries = NULL, *princ_s[18];; + char **oldEntries = NULL, *princ_s[26]; + + memset(princ_s, '\0', sizeof(princ_s)); ret = ads_keytab_add_entry(ads, "host"); if (ret) { @@ -472,6 +474,11 @@ int ads_keytab_create_default(ADS_STRUCT *ads) fstrcat(my_Fqdn, p_fqdn); } + fstrcpy(my_host_realm, my_name); + fstrcat(my_host_realm, "."); + fstrcat(my_host_realm, lp_realm()); + strlower_m(my_host_realm); + asprintf(&princ_s[0], "%s$@%s", my_name, lp_realm()); asprintf(&princ_s[1], "%s$@%s", my_NAME, lp_realm()); asprintf(&princ_s[2], "host/%s@%s", my_name, lp_realm()); @@ -490,6 +497,18 @@ int ads_keytab_create_default(ADS_STRUCT *ads) asprintf(&princ_s[15], "CIFS/%s@%s", my_NAME, lp_realm()); asprintf(&princ_s[16], "CIFS/%s@%s", my_fqdn, lp_realm()); asprintf(&princ_s[17], "CIFS/%s@%s", my_Fqdn, lp_realm()); + asprintf(&princ_s[18], "cifs/%s.%s@%s", my_name, lp_realm(), lp_realm()); + asprintf(&princ_s[19], "CIFS/%s.%s@%s", my_name, lp_realm(), lp_realm()); + asprintf(&princ_s[20], "host/%s.%s@%s", my_name, lp_realm(), lp_realm()); + asprintf(&princ_s[21], "HOST/%s.%s@%s", my_name, lp_realm(), lp_realm()); + + /* when dnsdomain == realm, don't add duplicate principal */ + if (!strequal(my_host_realm, my_fqdn)) { + asprintf(&princ_s[22], "cifs/%s@%s", my_host_realm, lp_realm()); + asprintf(&princ_s[23], "CIFS/%s@%s", my_host_realm, lp_realm()); + asprintf(&princ_s[24], "host/%s@%s", my_host_realm, lp_realm()); + asprintf(&princ_s[25], "HOST/%s@%s", my_host_realm, lp_realm()); + } for (i = 0; i < sizeof(princ_s) / sizeof(princ_s[0]); i++) { if (princ_s[i] != NULL) { -- cgit From 08af1e6dccd479d4819dfdac28b8c3efc38d8174 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 12 Mar 2005 01:28:10 +0000 Subject: r5762: Modified version of patch from Michael Brown to case insentively search for a principal match on logon verification in the system keytab. UNTESTED (although it compiles). Please test. Jeremy. (This used to be commit 1ace2ca1be65b4d6e92a98040fd09fdca74e8c8a) --- source3/libads/kerberos_verify.c | 164 +++++++++++++++++++++++---------------- 1 file changed, 99 insertions(+), 65 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index d73fc28a29..d6cca79318 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -42,12 +42,33 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut krb5_error_code ret = 0; BOOL auth_ok = False; krb5_keytab keytab = NULL; - fstring my_fqdn, my_name; - fstring my_Fqdn, my_NAME; - char *p_fqdn; - char *host_princ_s[18]; - krb5_principal host_princ; + krb5_kt_cursor kt_cursor; + krb5_keytab_entry kt_entry; + char *valid_princ_formats[7] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL }; + char *entry_princ_s = NULL; + fstring my_name, my_fqdn; int i; + int number_matched_principals = 0; + + /* Generate the list of principal names which we expect + * clients might want to use for authenticating to the file + * service. We allow name$,{host,cifs}/{name,fqdn,name.REALM}. */ + + fstrcpy(my_name, global_myname()); + + my_fqdn[0] = '\0'; + name_to_fqdn(my_fqdn, global_myname()); + + asprintf(&valid_princ_formats[0], "%s$@%s", my_name, lp_realm()); + asprintf(&valid_princ_formats[1], "host/%s@%s", my_name, lp_realm()); + asprintf(&valid_princ_formats[2], "host/%s@%s", my_fqdn, lp_realm()); + asprintf(&valid_princ_formats[3], "host/%s.%s@%s", my_name, lp_realm(), lp_realm()); + asprintf(&valid_princ_formats[4], "cifs/%s@%s", my_name, lp_realm()); + asprintf(&valid_princ_formats[5], "cifs/%s@%s", my_fqdn, lp_realm()); + asprintf(&valid_princ_formats[6], "cifs/%s.%s@%s", my_name, lp_realm(), lp_realm()); + + ZERO_STRUCT(kt_entry); + ZERO_STRUCT(kt_cursor); ret = krb5_kt_default(context, &keytab); if (ret) { @@ -55,74 +76,87 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut goto out; } - /* Generate the list of principal names which we expect clients might - * want to use for authenticating to the file service. */ + /* Iterate through the keytab. For each key, if the principal + * name case-insensitively matches one of the allowed formats, + * try verifying the ticket using that principal. */ - fstrcpy(my_name, global_myname()); - strlower_m(my_name); + ret = krb5_kt_start_seq_get(context, keytab, &kt_cursor); + if (ret) { + DEBUG(1, ("ads_keytab_verify_ticket: krb5_kt_start_seq_get failed (%s)\n", error_message(ret))); + goto out; + } + + ret = krb5_kt_start_seq_get(context, keytab, &kt_cursor); + if (ret != KRB5_KT_END && ret != ENOENT ) { + while (!auth_ok && (krb5_kt_next_entry(context, keytab, &kt_entry, &kt_cursor) == 0)) { + ret = krb5_unparse_name(context, kt_entry.principal, &entry_princ_s); + if (ret) { + DEBUG(1, ("ads_keytab_verify_ticket: krb5_unparse_name failed (%s)\n", error_message(ret))); + goto out; + } + + for (i = 0; i < sizeof(valid_princ_formats) / sizeof(valid_princ_formats[0]); i++) { + if (strequal(entry_princ_s, valid_princ_formats[i])) { + number_matched_principals++; + p_packet->length = ticket->length; + p_packet->data = (krb5_pointer)ticket->data; + *pp_tkt = NULL; + ret = krb5_rd_req(context, &auth_context, p_packet, kt_entry.principal, keytab, NULL, pp_tkt); + if (ret) { + DEBUG(10, ("ads_keytab_verify_ticket: krb5_rd_req(%s) failed: %s\n", + entry_princ_s, error_message(ret))); + } else { + DEBUG(3,("ads_keytab_verify_ticket: krb5_rd_req succeeded for principal %s\n", + entry_princ_s)); + auth_ok = True; + break; + } + } + } + + /* Free the name we parsed. */ + krb5_free_unparsed_name(context, entry_princ_s); + entry_princ_s = NULL; + + /* Free the entry we just read. */ + smb_krb5_kt_free_entry(context, &kt_entry); + ZERO_STRUCT(kt_entry); + } + krb5_kt_end_seq_get(context, keytab, &kt_cursor); + } - fstrcpy(my_NAME, global_myname()); - strupper_m(my_NAME); + ZERO_STRUCT(kt_cursor); - my_fqdn[0] = '\0'; - name_to_fqdn(my_fqdn, global_myname()); - strlower_m(my_fqdn); - - p_fqdn = strchr_m(my_fqdn, '.'); - fstrcpy(my_Fqdn, my_NAME); - if (p_fqdn) { - fstrcat(my_Fqdn, p_fqdn); - } - - asprintf(&host_princ_s[0], "%s$@%s", my_name, lp_realm()); - asprintf(&host_princ_s[1], "%s$@%s", my_NAME, lp_realm()); - asprintf(&host_princ_s[2], "host/%s@%s", my_name, lp_realm()); - asprintf(&host_princ_s[3], "host/%s@%s", my_NAME, lp_realm()); - asprintf(&host_princ_s[4], "host/%s@%s", my_fqdn, lp_realm()); - asprintf(&host_princ_s[5], "host/%s@%s", my_Fqdn, lp_realm()); - asprintf(&host_princ_s[6], "HOST/%s@%s", my_name, lp_realm()); - asprintf(&host_princ_s[7], "HOST/%s@%s", my_NAME, lp_realm()); - asprintf(&host_princ_s[8], "HOST/%s@%s", my_fqdn, lp_realm()); - asprintf(&host_princ_s[9], "HOST/%s@%s", my_Fqdn, lp_realm()); - asprintf(&host_princ_s[10], "cifs/%s@%s", my_name, lp_realm()); - asprintf(&host_princ_s[11], "cifs/%s@%s", my_NAME, lp_realm()); - asprintf(&host_princ_s[12], "cifs/%s@%s", my_fqdn, lp_realm()); - asprintf(&host_princ_s[13], "cifs/%s@%s", my_Fqdn, lp_realm()); - asprintf(&host_princ_s[14], "CIFS/%s@%s", my_name, lp_realm()); - asprintf(&host_princ_s[15], "CIFS/%s@%s", my_NAME, lp_realm()); - asprintf(&host_princ_s[16], "CIFS/%s@%s", my_fqdn, lp_realm()); - asprintf(&host_princ_s[17], "CIFS/%s@%s", my_Fqdn, lp_realm()); - - /* Now try to verify the ticket using the key associated with each of - * the principals which we think clients will expect us to be - * participating as. */ - for (i = 0; i < sizeof(host_princ_s) / sizeof(host_princ_s[0]); i++) { - host_princ = NULL; - ret = krb5_parse_name(context, host_princ_s[i], &host_princ); - if (ret) { - DEBUG(1, ("ads_keytab_verify_ticket: krb5_parse_name(%s) failed (%s)\n", - host_princ_s[i], error_message(ret))); - goto out; - } - p_packet->length = ticket->length; - p_packet->data = (krb5_pointer)ticket->data; - *pp_tkt = NULL; - ret = krb5_rd_req(context, &auth_context, p_packet, host_princ, keytab, NULL, pp_tkt); - krb5_free_principal(context, host_princ); - if (ret) { - DEBUG(10, ("krb5_rd_req(%s) failed: %s\n", host_princ_s[i], error_message(ret))); + out: + + if (!auth_ok) { + if (!number_matched_principals) { + DEBUG(3, ("ads_keytab_verify_ticket: no keytab principals matched expected file service name.\n")); } else { - DEBUG(10,("krb5_rd_req succeeded for principal %s\n", host_princ_s[i])); - auth_ok = True; - break; - } + DEBUG(3, ("ads_keytab_verify_ticket: krb5_rd_req failed for all %d matched keytab principals\n", + number_matched_principals)); + } } - for (i = 0; i < sizeof(host_princ_s) / sizeof(host_princ_s[0]); i++) { - SAFE_FREE(host_princ_s[i]); + if (entry_princ_s) { + krb5_free_unparsed_name(context, entry_princ_s); } - out: + { + krb5_keytab_entry zero_kt_entry; + ZERO_STRUCT(zero_kt_entry); + if (memcmp(&zero_kt_entry, &kt_entry, sizeof(krb5_keytab_entry))) { + smb_krb5_kt_free_entry(context, &kt_entry); + } + } + + { + krb5_kt_cursor zero_csr; + ZERO_STRUCT(zero_csr); + if ((memcmp(&kt_cursor, &zero_csr, sizeof(krb5_kt_cursor)) != 0) && keytab) { + krb5_kt_end_seq_get(context, keytab, &kt_cursor); + } + } if (keytab) { krb5_kt_close(context, keytab); -- cgit From 40295c41dbba119f6b4e32647fb70f51ebf390a0 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 22 Mar 2005 14:48:18 +0000 Subject: r5948: more compile cleanups from Jason Mader (This used to be commit cc6c769c3c26164919dd13777d671abe02c084d9) --- source3/libads/ldap.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 6e1b011c37..13e6aa5a31 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1267,7 +1267,7 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n ADS_STATUS ret; TALLOC_CTX *ctx; LDAPMessage *res = NULL; - char *host_spn, *host_upn, *psp1, *psp2, *psp3; + char *host_spn, *psp1, *psp2, *psp3; ADS_MODLIST mods; fstring my_fqdn; char *dn_string = NULL; @@ -1297,11 +1297,6 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_SUCH_OBJECT); } - if (!(host_upn = talloc_asprintf(ctx, "%s@%s", host_spn, ads->config.realm))) { - talloc_destroy(ctx); - ads_msgfree(ads, res); - return ADS_ERROR(LDAP_NO_SUCH_OBJECT); - } /* Add the extra principal */ psp1 = talloc_asprintf(ctx, "%s/%s", spn, machine_name); -- cgit From 4b831f8e16d305666b0f2b018c35f5427efc21cc Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 22 Mar 2005 15:12:50 +0000 Subject: r5952: BUG 2469: patch from Jason Mader to cleanup compiler warning when not using krb5 (This used to be commit 19a639ac468237b22f16d917c0150fbf10c9623e) --- source3/libads/sasl.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 97ba9c9286..0164b0c740 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -173,7 +173,9 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) DATA_BLOB blob; char *principal = NULL; char *OIDs[ASN1_MAX_OIDS]; +#ifdef HAVE_KRB5 BOOL got_kerberos_mechanism = False; +#endif rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", NULL, NULL, NULL, &scred); @@ -202,10 +204,12 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) /* make sure the server understands kerberos */ for (i=0;OIDs[i];i++) { DEBUG(3,("ads_sasl_spnego_bind: got OID=%s\n", OIDs[i])); +#ifdef HAVE_KRB5 if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 || strcmp(OIDs[i], OID_KERBEROS5) == 0) { got_kerberos_mechanism = True; } +#endif free(OIDs[i]); } DEBUG(3,("ads_sasl_spnego_bind: got server principal name =%s\n", principal)); -- cgit From 73d1950c010777605b1294397002cc7aa011add0 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 22 Mar 2005 16:39:09 +0000 Subject: r5956: more compile warngin fixes from the Mr. Mader (This used to be commit f3f315b14d261fa56ab040db036a6f858ac06e65) --- source3/libads/ldap.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 13e6aa5a31..68103a701b 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -831,7 +831,7 @@ ADS_MODLIST ads_init_mods(TALLOC_CTX *ctx) need to reset it to NULL before doing ldap modify */ mods[ADS_MODLIST_ALLOC_SIZE] = (LDAPMod *) -1; - return mods; + return (ADS_MODLIST)mods; } @@ -868,7 +868,7 @@ static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, memset(&modlist[curmod], 0, ADS_MODLIST_ALLOC_SIZE*sizeof(LDAPMod *)); modlist[curmod+ADS_MODLIST_ALLOC_SIZE] = (LDAPMod *) -1; - *mods = modlist; + *mods = (ADS_MODLIST)modlist; } if (!(modlist[curmod] = TALLOC_ZERO_P(ctx, LDAPMod))) @@ -1006,7 +1006,7 @@ ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ADS_MODLIST mods) /* make sure the end of the list is NULL */ mods[i] = NULL; - ret = ldap_add_s(ads->ld, utf8_dn, mods); + ret = ldap_add_s(ads->ld, utf8_dn, (LDAPMod**)mods); SAFE_FREE(utf8_dn); return ADS_ERROR(ret); } -- cgit From 934d41d23956c663406ff9d68e5a8ba9d81b5096 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Wed, 30 Mar 2005 04:40:24 +0000 Subject: r6127: Eliminated all compiler warnings pertaining to mismatched "qualifiers". The whole of samba comiles warning-free with the default compiler flags. Temporarily defined -Wall to locate other potential problems. Found an unused static function (#ifdefed out rather than deleted, in case it's needed for something in progress). There are also a number of uses of undeclared functions, mostly krb5_*. Files with these problems need to have appropriate header files included, but they are not fixed in this update. oplock_linux.c.c has undefined functions capget() and capset(), which need to have "#undef _POSIX_SOURCE" specified before including , but that could potentially have other side effects, so that remains uncorrected as well. The flag -Wall should be added permanently to CFLAGS, and all warnings then generated should be eliminated. (This used to be commit 5b19ede88ed80318e392f8017f4573fbb2ecbe0f) --- source3/libads/kerberos.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 4c9997e080..43ccb18b5a 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -88,7 +88,8 @@ int kerberos_kinit_password(const char *principal, return code; } - if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, password, + if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, + (char *) password, kerb_prompter, NULL, 0, NULL, NULL))) { krb5_free_principal(ctx, me); -- cgit From 9840db418bad5a39edc4a32a1786f5e2d2c9dff8 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Thu, 31 Mar 2005 05:06:04 +0000 Subject: r6149: Fixes bugs #2498 and 2484. 1. using smbc_getxattr() et al, one may now request all access control entities in the ACL without getting all other NT attributes. 2. added the ability to exclude specified attributes from the result set provided by smbc_getxattr() et al, when requesting all attributes, all NT attributes, or all DOS attributes. 3. eliminated all compiler warnings, including when --enable-developer compiler flags are in use. removed -Wcast-qual flag from list, as that is specifically to force warnings in the case of casting away qualifiers. Note: In the process of eliminating compiler warnings, a few nasties were discovered. In the file libads/sasl.c, PRIVATE kerberos interfaces are being used; and in libsmb/clikrb5.c, both PRIAVE and DEPRECATED kerberos interfaces are being used. Someone who knows kerberos should look at these and determine if there is an alternate method of accomplishing the task. (This used to be commit 994694f7f26da5099f071e1381271a70407f33bb) --- source3/libads/kerberos.c | 2 +- source3/libads/ldap.c | 8 ++++---- source3/libads/ldap_printer.c | 6 ++++-- source3/libads/sasl.c | 5 ++++- 4 files changed, 13 insertions(+), 8 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 43ccb18b5a..18820d9e31 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -89,7 +89,7 @@ int kerberos_kinit_password(const char *principal, } if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, - (char *) password, + CONST_DISCARD(char *, password), kerb_prompter, NULL, 0, NULL, NULL))) { krb5_free_principal(ctx, me); diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 68103a701b..7a59da5a6d 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -481,15 +481,15 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, ber_printf(cookie_be, "{io}", (ber_int_t) 1000, "", 0); } ber_flatten(cookie_be, &cookie_bv); - PagedResults.ldctl_oid = ADS_PAGE_CTL_OID; + PagedResults.ldctl_oid = CONST_DISCARD(char *, ADS_PAGE_CTL_OID); PagedResults.ldctl_iscritical = (char) 1; PagedResults.ldctl_value.bv_len = cookie_bv->bv_len; PagedResults.ldctl_value.bv_val = cookie_bv->bv_val; - NoReferrals.ldctl_oid = ADS_NO_REFERRALS_OID; + NoReferrals.ldctl_oid = CONST_DISCARD(char *, ADS_NO_REFERRALS_OID); NoReferrals.ldctl_iscritical = (char) 0; NoReferrals.ldctl_value.bv_len = 0; - NoReferrals.ldctl_value.bv_val = ""; + NoReferrals.ldctl_value.bv_val = CONST_DISCARD(char *, ""); controls[0] = &NoReferrals; @@ -962,7 +962,7 @@ ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, ADS_MODLIST mods) non-existent attribute (but allowable for the object) to run */ LDAPControl PermitModify = { - ADS_PERMIT_MODIFY_OID, + CONST_DISCARD(char *, ADS_PERMIT_MODIFY_OID), {0, NULL}, (char) 1}; LDAPControl *controls[2]; diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index 68e6735891..61275e40d1 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -61,8 +61,10 @@ ADS_STATUS ads_find_printers(ADS_STRUCT *ads, void **res) /* For the moment only display all printers */ - ldap_expr = "(&(!(showInAdvancedViewOnly=TRUE))(uncName=*)" - "(objectCategory=printQueue))"; + ldap_expr = + CONST_DISCARD(char *, + "(&(!(showInAdvancedViewOnly=TRUE))(uncName=*)" + "(objectCategory=printQueue))"); return ads_search(ads, res, ldap_expr, attrs); } diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 0164b0c740..e657f2114e 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -18,6 +18,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#define KRB5_PRIVATE 1 /* this file uses PRIVATE interfaces! */ + #include "includes.h" #ifdef HAVE_LDAP @@ -285,7 +287,8 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) ENCTYPE_DES_CBC_MD5, ENCTYPE_NULL}; gss_OID_desc nt_principal = - {10, "\052\206\110\206\367\022\001\002\002\002"}; + {10, CONST_DISCARD(char *, + "\052\206\110\206\367\022\001\002\002\002")}; /* we need to fetch a service ticket as the ldap user in the servers realm, regardless of our realm */ -- cgit From 1c4bbe06549d86614318718a45b9bc48e3bfc81f Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Mon, 2 May 2005 17:49:43 +0000 Subject: r6586: get rid of a few more compiler warnings (This used to be commit 173375f8d88bf8e8db8d60e5d5f0e5dcc28767d9) --- source3/libads/kerberos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 18820d9e31..902feb2eee 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -248,7 +248,7 @@ krb5_principal kerberos_fetch_salt_princ_for_host_princ(krb5_context context, Setting principal to NULL deletes this entry. ************************************************************************/ - BOOL kerberos_secrets_store_salting_principal(const char *service, +BOOL kerberos_secrets_store_salting_principal(const char *service, int enctype, const char *principal) { -- cgit From 7b9d6ac23e1a7d8136fffd2e3977b09a815da65a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 3 May 2005 07:33:49 +0000 Subject: r6595: This is Volkers new-talloc patch. Just got the go-ahead from Volker to commit. Woo Hoo ! Jeremy. (This used to be commit 316df944a456f150944761dab34add5e8c4ab699) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 7a59da5a6d..04754f4e9e 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1703,7 +1703,7 @@ void ads_process_results(ADS_STRUCT *ads, void *res, ldap_memfree(utf8_field); } ber_free(b, 0); - talloc_destroy_pool(ctx); + talloc_free_children(ctx); fn(NULL, NULL, data_area); /* completed an entry */ } -- cgit From f24d88cf9da46680d52b42b92bd484e7b09ce99b Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 31 May 2005 13:46:45 +0000 Subject: r7139: trying to reduce the number of diffs between trunk and 3.0; changing version to 3.0.20pre1 (This used to be commit 9727d05241574042dd3aa8844ae5c701d22e2da1) --- source3/libads/ldap_printer.c | 6 ++---- source3/libads/sasl.c | 5 +---- 2 files changed, 3 insertions(+), 8 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index 61275e40d1..68e6735891 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -61,10 +61,8 @@ ADS_STATUS ads_find_printers(ADS_STRUCT *ads, void **res) /* For the moment only display all printers */ - ldap_expr = - CONST_DISCARD(char *, - "(&(!(showInAdvancedViewOnly=TRUE))(uncName=*)" - "(objectCategory=printQueue))"); + ldap_expr = "(&(!(showInAdvancedViewOnly=TRUE))(uncName=*)" + "(objectCategory=printQueue))"; return ads_search(ads, res, ldap_expr, attrs); } diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index e657f2114e..0164b0c740 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -18,8 +18,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define KRB5_PRIVATE 1 /* this file uses PRIVATE interfaces! */ - #include "includes.h" #ifdef HAVE_LDAP @@ -287,8 +285,7 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) ENCTYPE_DES_CBC_MD5, ENCTYPE_NULL}; gss_OID_desc nt_principal = - {10, CONST_DISCARD(char *, - "\052\206\110\206\367\022\001\002\002\002")}; + {10, "\052\206\110\206\367\022\001\002\002\002"}; /* we need to fetch a service ticket as the ldap user in the servers realm, regardless of our realm */ -- cgit From fed660877c16562265327c6093ea645cf4176b5c Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 8 Jun 2005 22:10:34 +0000 Subject: r7415: * big change -- volker's new async winbindd from trunk (This used to be commit a0ac9a8ffd4af31a0ebc423b4acbb2f043d865b8) --- source3/libads/kerberos.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 902feb2eee..c25f9e4bde 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -88,8 +88,7 @@ int kerberos_kinit_password(const char *principal, return code; } - if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, - CONST_DISCARD(char *, password), + if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, password, kerb_prompter, NULL, 0, NULL, NULL))) { krb5_free_principal(ctx, me); -- cgit From 2e7f22e833fbb549f698460f9ed4d81af68b86e9 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 29 Jun 2005 14:03:53 +0000 Subject: r7994: This adds support in Winbindd's "security = ads"-mode to retrieve the POSIX homedirectory and the loginshell from Active Directory's "Services for Unix". Enable it with: winbind sfu support = yes User-Accounts without SFU-Unix-Attributes will be assigned template-based Shells and Homedirs as before. Note that it doesn't matter which version of Services for Unix you use (2.0, 2.2, 3.0 or 3.5). Samba should detect the correct attributes (msSFULoginShell, msSFU30LoginShell, etc.) automatically. If you also want to share the same uid/gid-space as SFU then also use PADL's ad-idmap-Plugin: idmap backend = ad When using the idmap-plugin only those accounts will appear in Name Service Switch that have those UNIX-attributes which avoids potential uid/gid-space clashes between SFU-ids and automatically assigned idmap-ids. Guenther (This used to be commit 28b59699425b1c954d191fc0e3bd357e4a4e4cd8) --- source3/libads/ads_struct.c | 5 +++ source3/libads/ldap.c | 96 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 100 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index e8546f86f5..d8676d050d 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -132,8 +132,13 @@ void ads_destroy(ADS_STRUCT **ads) SAFE_FREE((*ads)->config.realm); SAFE_FREE((*ads)->config.bind_path); + SAFE_FREE((*ads)->config.schema_path); SAFE_FREE((*ads)->config.ldap_server_name); + SAFE_FREE((*ads)->schema.sfu_uidnumber_attr); + SAFE_FREE((*ads)->schema.sfu_gidnumber_attr); + SAFE_FREE((*ads)->schema.sfu_shell_attr); + SAFE_FREE((*ads)->schema.sfu_homedir_attr); ZERO_STRUCTP(*ads); diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 04754f4e9e..1289015464 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2388,6 +2388,43 @@ static time_t ads_parse_time(const char *str) } +const char *ads_get_attrname_by_oid(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char * oid) +{ + ADS_STATUS rc; + int count = 0; + void *res = NULL; + char *expr = NULL; + const char *attrs[] = { "lDAPDisplayName", NULL }; + + if (ads == NULL || mem_ctx == NULL || oid == NULL) { + goto done; + } + + expr = talloc_asprintf(mem_ctx, "(attributeId=%s)", oid); + if (expr == NULL) { + goto done; + } + + rc = ads_do_search_retry(ads, ads->config.schema_path, + LDAP_SCOPE_SUBTREE, expr, attrs, &res); + if (!ADS_ERR_OK(rc)) { + goto done; + } + + count = ads_count_replies(ads, res); + if (count == 0 || !res) { + goto done; + } + + return ads_pull_string(ads, mem_ctx, res, "lDAPDisplayName"); + +done: + DEBUG(0,("ads_get_attrname_by_oid: failed to retrieve name for oid: %s\n", + oid)); + + return NULL; +} + /** * Find the servers name and realm - this can be done before authentication * The ldapServiceName field on w2k looks like this: @@ -2397,12 +2434,15 @@ static time_t ads_parse_time(const char *str) **/ ADS_STATUS ads_server_info(ADS_STRUCT *ads) { - const char *attrs[] = {"ldapServiceName", "currentTime", NULL}; + const char *attrs[] = {"ldapServiceName", + "currentTime", + "schemaNamingContext", NULL}; ADS_STATUS status; void *res; char *value; char *p; char *timestr; + char *schema_path; TALLOC_CTX *ctx; if (!(ctx = talloc_init("ads_server_info"))) { @@ -2429,6 +2469,16 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads) return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); } + schema_path = ads_pull_string(ads, ctx, res, "schemaNamingContext"); + if (!schema_path) { + ads_msgfree(ads, res); + talloc_destroy(ctx); + return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); + } + + SAFE_FREE(ads->config.schema_path); + ads->config.schema_path = SMB_STRDUP(schema_path); + ads_msgfree(ads, res); p = strchr(value, ':'); @@ -2475,6 +2525,50 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads) return ADS_SUCCESS; } +/** + * Check for "Services for Unix"-Schema and load some attributes into the ADS_STRUCT + * @param ads connection to ads server + * @return BOOL status of search (False if one or more attributes couldn't be + * found in Active Directory) + **/ +BOOL ads_check_sfu_mapping(ADS_STRUCT *ads) +{ + BOOL ret = False; + TALLOC_CTX *ctx = NULL; + const char *gidnumber, *uidnumber, *homedir, *shell; + + ctx = talloc_init("ads_check_sfu_mapping"); + if (ctx == NULL) + goto done; + + gidnumber = ads_get_attrname_by_oid(ads, ctx, ADS_ATTR_SFU_GIDNUMBER_OID); + if (gidnumber == NULL) + goto done; + ads->schema.sfu_gidnumber_attr = SMB_STRDUP(gidnumber); + + uidnumber = ads_get_attrname_by_oid(ads, ctx, ADS_ATTR_SFU_UIDNUMBER_OID); + if (uidnumber == NULL) + goto done; + ads->schema.sfu_uidnumber_attr = SMB_STRDUP(uidnumber); + + homedir = ads_get_attrname_by_oid(ads, ctx, ADS_ATTR_SFU_HOMEDIR_OID); + if (homedir == NULL) + goto done; + ads->schema.sfu_homedir_attr = SMB_STRDUP(homedir); + + shell = ads_get_attrname_by_oid(ads, ctx, ADS_ATTR_SFU_SHELL_OID); + if (shell == NULL) + goto done; + ads->schema.sfu_shell_attr = SMB_STRDUP(shell); + + ret = True; +done: + if (ctx) + talloc_destroy(ctx); + + return ret; +} + /** * find the domain sid for our domain * @param ads connection to ads server -- cgit From 3f11139bf361ecc9dbcf928c48c67f2fdb95b771 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 1 Jul 2005 10:20:28 +0000 Subject: r8047: "oid" is defined in a heimdal header. With my gcc this generates a ton of shadowed variable warnings. Fix that. Volker (This used to be commit 3846c0afa1db96239b3aaf2e7ee2427b48f6e2f0) --- source3/libads/ldap.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 1289015464..b3faad1fb1 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2388,7 +2388,7 @@ static time_t ads_parse_time(const char *str) } -const char *ads_get_attrname_by_oid(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char * oid) +const char *ads_get_attrname_by_oid(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char * OID) { ADS_STATUS rc; int count = 0; @@ -2396,11 +2396,11 @@ const char *ads_get_attrname_by_oid(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char *expr = NULL; const char *attrs[] = { "lDAPDisplayName", NULL }; - if (ads == NULL || mem_ctx == NULL || oid == NULL) { + if (ads == NULL || mem_ctx == NULL || OID == NULL) { goto done; } - expr = talloc_asprintf(mem_ctx, "(attributeId=%s)", oid); + expr = talloc_asprintf(mem_ctx, "(attributeId=%s)", OID); if (expr == NULL) { goto done; } @@ -2420,7 +2420,7 @@ const char *ads_get_attrname_by_oid(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const done: DEBUG(0,("ads_get_attrname_by_oid: failed to retrieve name for oid: %s\n", - oid)); + OID)); return NULL; } -- cgit From 065d7e82a74166d06cb99678109d6de5d25e2298 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 1 Jul 2005 10:28:31 +0000 Subject: r8048: Replace "done" with "failed". Guenther (This used to be commit 7285edc4fe71f47ab648c31760c357fc2af29ce7) --- source3/libads/ldap.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index b3faad1fb1..81afd7f49e 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2397,28 +2397,28 @@ const char *ads_get_attrname_by_oid(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const const char *attrs[] = { "lDAPDisplayName", NULL }; if (ads == NULL || mem_ctx == NULL || OID == NULL) { - goto done; + goto failed; } expr = talloc_asprintf(mem_ctx, "(attributeId=%s)", OID); if (expr == NULL) { - goto done; + goto failed; } rc = ads_do_search_retry(ads, ads->config.schema_path, LDAP_SCOPE_SUBTREE, expr, attrs, &res); if (!ADS_ERR_OK(rc)) { - goto done; + goto failed; } count = ads_count_replies(ads, res); if (count == 0 || !res) { - goto done; + goto failed; } return ads_pull_string(ads, mem_ctx, res, "lDAPDisplayName"); -done: +failed: DEBUG(0,("ads_get_attrname_by_oid: failed to retrieve name for oid: %s\n", OID)); -- cgit From f88e4babab2b3060c235389a71d2e96925237fd0 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 1 Jul 2005 19:23:50 +0000 Subject: r8062: Remove some unused code (This used to be commit fa6cc0bdefe272ec538a71a2b6ba72a724411764) --- source3/libads/ads_ldap.c | 129 ---------------------------------------------- 1 file changed, 129 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_ldap.c b/source3/libads/ads_ldap.c index 944cb1599c..ae86ef0b76 100644 --- a/source3/libads/ads_ldap.c +++ b/source3/libads/ads_ldap.c @@ -24,135 +24,6 @@ #include "includes.h" #ifdef HAVE_LDAP -/* convert a single name to a sid in a domain */ -NTSTATUS ads_name_to_sid(ADS_STRUCT *ads, - const char *name, - DOM_SID *sid, - enum SID_NAME_USE *type) -{ - const char *attrs[] = {"objectSid", "sAMAccountType", NULL}; - int count; - ADS_STATUS rc; - void *res = NULL; - char *ldap_exp; - uint32 t; - NTSTATUS status = NT_STATUS_UNSUCCESSFUL; - char *escaped_name = escape_ldap_string_alloc(name); - char *escaped_realm = escape_ldap_string_alloc(ads->config.realm); - - if (!escaped_name || !escaped_realm) { - status = NT_STATUS_NO_MEMORY; - goto done; - } - - if (asprintf(&ldap_exp, "(|(sAMAccountName=%s)(userPrincipalName=%s@%s))", - escaped_name, escaped_name, escaped_realm) == -1) { - DEBUG(1,("ads_name_to_sid: asprintf failed!\n")); - status = NT_STATUS_NO_MEMORY; - goto done; - } - - rc = ads_search_retry(ads, &res, ldap_exp, attrs); - free(ldap_exp); - if (!ADS_ERR_OK(rc)) { - DEBUG(1,("name_to_sid ads_search: %s\n", ads_errstr(rc))); - goto done; - } - - count = ads_count_replies(ads, res); - if (count != 1) { - DEBUG(1,("name_to_sid: %s not found\n", name)); - goto done; - } - - if (!ads_pull_sid(ads, res, "objectSid", sid)) { - DEBUG(1,("No sid for %s !?\n", name)); - goto done; - } - - if (!ads_pull_uint32(ads, res, "sAMAccountType", &t)) { - DEBUG(1,("No sAMAccountType for %s !?\n", name)); - goto done; - } - - *type = ads_atype_map(t); - - status = NT_STATUS_OK; - - DEBUG(3,("ads name_to_sid mapped %s\n", name)); - -done: - if (res) ads_msgfree(ads, res); - - SAFE_FREE(escaped_name); - SAFE_FREE(escaped_realm); - - return status; -} - -/* convert a sid to a user or group name */ -NTSTATUS ads_sid_to_name(ADS_STRUCT *ads, - TALLOC_CTX *mem_ctx, - const DOM_SID *sid, - char **name, - enum SID_NAME_USE *type) -{ - const char *attrs[] = {"userPrincipalName", - "sAMAccountName", - "sAMAccountType", NULL}; - ADS_STATUS rc; - void *msg = NULL; - char *ldap_exp = NULL; - char *sidstr = NULL; - uint32 atype; - NTSTATUS status = NT_STATUS_UNSUCCESSFUL; - - if (!(sidstr = sid_binstring(sid))) { - DEBUG(1,("ads_sid_to_name: sid_binstring failed!\n")); - status = NT_STATUS_NO_MEMORY; - goto done; - } - - if (asprintf(&ldap_exp, "(objectSid=%s)", sidstr) == -1) { - DEBUG(1,("ads_sid_to_name: asprintf failed!\n")); - status = NT_STATUS_NO_MEMORY; - goto done; - } - - rc = ads_search_retry(ads, &msg, ldap_exp, attrs); - if (!ADS_ERR_OK(rc)) { - status = ads_ntstatus(rc); - DEBUG(1,("ads_sid_to_name ads_search: %s\n", ads_errstr(rc))); - goto done; - } - - if (!ads_pull_uint32(ads, msg, "sAMAccountType", &atype)) { - goto done; - } - - *name = ads_pull_username(ads, mem_ctx, msg); - if (!*name) { - DEBUG(1,("ads_sid_to_name: ads_pull_username retuned NULL!\n")); - status = NT_STATUS_NO_MEMORY; - goto done; - } - - *type = ads_atype_map(atype); - - status = NT_STATUS_OK; - - DEBUG(3,("ads sid_to_name mapped %s\n", *name)); - -done: - if (msg) ads_msgfree(ads, msg); - - SAFE_FREE(ldap_exp); - SAFE_FREE(sidstr); - - return status; -} - - /* convert a sid to a DN */ ADS_STATUS ads_sid_to_dn(ADS_STRUCT *ads, -- cgit From ecafd3754f35a2109a3a1eecbbdd72ade06b8502 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 20 Jul 2005 15:35:29 +0000 Subject: r8654: merging cli_spoolss_XX() updates from trunk (This used to be commit cd961e50a3029898868d21263ccacb7d5f1f07b9) --- source3/libads/ldap_printer.c | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index 68e6735891..6b053f8b4a 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -267,7 +267,7 @@ WERROR get_remote_printer_publishing_data(struct cli_state *cli, char *printername, *servername; REGVAL_CTR dsdriver_ctr, dsspooler_ctr; BOOL got_dsdriver = False, got_dsspooler = False; - uint32 needed, i; + uint32 i; POLICY_HND pol; asprintf(&servername, "\\\\%s", cli->desthost); @@ -286,14 +286,7 @@ WERROR get_remote_printer_publishing_data(struct cli_state *cli, return result; } - result = cli_spoolss_enumprinterdataex(cli, mem_ctx, 0, &needed, - &pol, SPOOL_DSDRIVER_KEY, NULL); - - if (W_ERROR_V(result) == ERRmoredata) - result = cli_spoolss_enumprinterdataex(cli, mem_ctx, needed, - NULL, &pol, - SPOOL_DSDRIVER_KEY, - &dsdriver_ctr); + result = cli_spoolss_enumprinterdataex(cli, mem_ctx, &pol, SPOOL_DSDRIVER_KEY, NULL); if (!W_ERROR_IS_OK(result)) { DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n", @@ -307,15 +300,7 @@ WERROR get_remote_printer_publishing_data(struct cli_state *cli, dsdriver_ctr.values[i]); } - result = cli_spoolss_enumprinterdataex(cli, mem_ctx, 0, &needed, - &pol, SPOOL_DSSPOOLER_KEY, - NULL); - - if (W_ERROR_V(result) == ERRmoredata) - result = cli_spoolss_enumprinterdataex(cli, mem_ctx, needed, - NULL, &pol, - SPOOL_DSSPOOLER_KEY, - &dsspooler_ctr); + result = cli_spoolss_enumprinterdataex(cli, mem_ctx, &pol, SPOOL_DSSPOOLER_KEY, NULL); if (!W_ERROR_IS_OK(result)) { DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n", -- cgit From 63546f1c79db09c1d7032af8d941d6d9497280e7 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 21 Jul 2005 09:28:12 +0000 Subject: r8675: fix some compile warnings. Guenther (This used to be commit afa8ae831a8d9cde8c6474c5fc807a9ca8155273) --- source3/libads/ldap_printer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index 6b053f8b4a..9773296ae0 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -55,7 +55,7 @@ ADS_STATUS ads_find_printer_on_server(ADS_STRUCT *ads, void **res, ADS_STATUS ads_find_printers(ADS_STRUCT *ads, void **res) { - char *ldap_expr; + const char *ldap_expr; const char *attrs[] = { "objectClass", "printerName", "location", "driverName", "serverName", "description", NULL }; -- cgit From 14a9d52832b19a698968900da6378d542d6a21ce Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 1 Aug 2005 20:54:31 +0000 Subject: r8899: various compiler warning fixes reported by Jason Mader (This used to be commit d8ae9f2b3e5387ef2c4e84cd9c33f4a7c795b0d3) --- source3/libads/ldap_printer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index 9773296ae0..f4ecbdd93c 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -286,7 +286,7 @@ WERROR get_remote_printer_publishing_data(struct cli_state *cli, return result; } - result = cli_spoolss_enumprinterdataex(cli, mem_ctx, &pol, SPOOL_DSDRIVER_KEY, NULL); + result = cli_spoolss_enumprinterdataex(cli, mem_ctx, &pol, SPOOL_DSDRIVER_KEY, &dsdriver_ctr); if (!W_ERROR_IS_OK(result)) { DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n", @@ -300,7 +300,7 @@ WERROR get_remote_printer_publishing_data(struct cli_state *cli, dsdriver_ctr.values[i]); } - result = cli_spoolss_enumprinterdataex(cli, mem_ctx, &pol, SPOOL_DSSPOOLER_KEY, NULL); + result = cli_spoolss_enumprinterdataex(cli, mem_ctx, &pol, SPOOL_DSSPOOLER_KEY, &dsspooler_ctr); if (!W_ERROR_IS_OK(result)) { DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n", -- cgit From 4dec112b8a99183e1dc01fd8cacad3ece85d21da Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 3 Aug 2005 05:46:06 +0000 Subject: r8989: Fix a warning (This used to be commit 3d491ebf9ca8edae938aee08abb924905fd83deb) --- source3/libads/sasl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 0164b0c740..8fa62a5ade 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -285,7 +285,7 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) ENCTYPE_DES_CBC_MD5, ENCTYPE_NULL}; gss_OID_desc nt_principal = - {10, "\052\206\110\206\367\022\001\002\002\002"}; + {10, CONST_DISCARD(char *, "\052\206\110\206\367\022\001\002\002\002")}; /* we need to fetch a service ticket as the ldap user in the servers realm, regardless of our realm */ -- cgit From cc6843fcca2220d27235ff87c7f2b5b2403052ad Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sat, 6 Aug 2005 04:35:11 +0000 Subject: r9163: Rename UNKNOWN_TYPE_10 to PAC_LOGON_NAME (merge from samba4) Guenther (This used to be commit d14dcba9635d10d2d8bf9f60c601b8c9078ec340) --- source3/libads/authdata.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c index ccaf82124c..2cc6c6ebae 100644 --- a/source3/libads/authdata.c +++ b/source3/libads/authdata.c @@ -43,31 +43,31 @@ static DATA_BLOB unwrap_pac(DATA_BLOB *auth_data) return pac_contents; } -static BOOL pac_io_unknown_type_10(const char *desc, UNKNOWN_TYPE_10 *type_10, - prs_struct *ps, int depth) +static BOOL pac_io_logon_name(const char *desc, PAC_LOGON_NAME *logon_name, + prs_struct *ps, int depth) { - if (NULL == type_10) + if (NULL == logon_name) return False; - prs_debug(ps, depth, desc, "pac_io_unknown_type_10"); + prs_debug(ps, depth, desc, "pac_io_logon_name"); depth++; - if (!smb_io_time("unknown_time", &type_10->unknown_time, ps, depth)) + if (!smb_io_time("logon_time", &logon_name->logon_time, ps, depth)) return False; - if (!prs_uint16("len", ps, depth, &type_10->len)) + if (!prs_uint16("len", ps, depth, &logon_name->len)) return False; - if (UNMARSHALLING(ps) && type_10->len) { - type_10->username = PRS_ALLOC_MEM(ps, uint16, type_10->len); - if (!type_10->username) { + if (UNMARSHALLING(ps) && logon_name->len) { + logon_name->username = PRS_ALLOC_MEM(ps, uint16, logon_name->len); + if (!logon_name->username) { DEBUG(3, ("No memory available\n")); return False; } } - if (!prs_uint16s(True, "name", ps, depth, type_10->username, - (type_10->len / sizeof(uint16)))) + if (!prs_uint16s(True, "name", ps, depth, logon_name->username, + (logon_name->len / sizeof(uint16)))) return False; return True; @@ -499,15 +499,15 @@ static BOOL pac_io_pac_info_hdr_ctr(const char *desc, PAC_INFO_HDR *hdr, return False; break; - case PAC_TYPE_UNKNOWN_10: - DEBUG(5, ("PAC_TYPE_UNKNOWN_10\n")); + case PAC_TYPE_LOGON_NAME: + DEBUG(5, ("PAC_TYPE_LOGON_NAME\n")); if (UNMARSHALLING(ps)) - hdr->ctr->pac.type_10 = PRS_ALLOC_MEM(ps, UNKNOWN_TYPE_10, 1); - if (!hdr->ctr->pac.type_10) { + hdr->ctr->pac.logon_name = PRS_ALLOC_MEM(ps, PAC_LOGON_NAME, 1); + if (!hdr->ctr->pac.logon_name) { DEBUG(3, ("No memory available\n")); return False; } - if (!pac_io_unknown_type_10(desc, hdr->ctr->pac.type_10, + if (!pac_io_logon_name(desc, hdr->ctr->pac.logon_name, ps, depth)) return False; break; -- cgit From 44707ad2e00a91f459e80efbe8f362b5853b0a62 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 29 Aug 2005 14:55:40 +0000 Subject: r9739: conver the reg_objects (REGSUBKEY_CTR & REGVAL_CTR) to use the new talloc() features: Note that the REGSUB_CTR and REGVAL_CTR objects *must* be talloc()'d since the methods use the object pointer as the talloc context for internal private data. There is no longer a regXXX_ctr_intit() and regXXX_ctr_destroy() pair of functions. Simply TALLOC_ZERO_P() and TALLOC_FREE() the object. Also had to convert the printer_info_2->NT_PRINTER_DATA field to be talloc()'d as well. This is just a stop on the road to cleaning up the printer memory management. (This used to be commit ef721333ab9639cb5346067497e99fbd0d4425dd) --- source3/libads/ldap_printer.c | 41 ++++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 17 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index f4ecbdd93c..db544fe209 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -265,8 +265,7 @@ WERROR get_remote_printer_publishing_data(struct cli_state *cli, { WERROR result; char *printername, *servername; - REGVAL_CTR dsdriver_ctr, dsspooler_ctr; - BOOL got_dsdriver = False, got_dsspooler = False; + REGVAL_CTR *dsdriver_ctr, *dsspooler_ctr; uint32 i; POLICY_HND pol; @@ -286,36 +285,44 @@ WERROR get_remote_printer_publishing_data(struct cli_state *cli, return result; } - result = cli_spoolss_enumprinterdataex(cli, mem_ctx, &pol, SPOOL_DSDRIVER_KEY, &dsdriver_ctr); + if ( !(dsdriver_ctr = TALLOC_ZERO_P( mem_ctx, REGVAL_CTR )) ) + return WERR_NOMEM; + + result = cli_spoolss_enumprinterdataex(cli, mem_ctx, &pol, SPOOL_DSDRIVER_KEY, dsdriver_ctr); if (!W_ERROR_IS_OK(result)) { DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n", printername, dos_errstr(result))); } else { + uint32 num_values = regval_ctr_numvals( dsdriver_ctr ); /* Have the data we need now, so start building */ - got_dsdriver = True; - for (i=0; i < dsdriver_ctr.num_values; i++) - map_regval_to_ads(mem_ctx, mods, - dsdriver_ctr.values[i]); + for (i=0; i < num_values; i++) { + map_regval_to_ads(mem_ctx, mods, dsdriver_ctr->values[i]); + } } - result = cli_spoolss_enumprinterdataex(cli, mem_ctx, &pol, SPOOL_DSSPOOLER_KEY, &dsspooler_ctr); + if ( !(dsspooler_ctr = TALLOC_ZERO_P( mem_ctx, REGVAL_CTR )) ) + return WERR_NOMEM; + + result = cli_spoolss_enumprinterdataex(cli, mem_ctx, &pol, SPOOL_DSSPOOLER_KEY, dsspooler_ctr); if (!W_ERROR_IS_OK(result)) { DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n", printername, dos_errstr(result))); } else { - got_dsspooler = True; - for (i=0; i < dsspooler_ctr.num_values; i++) - map_regval_to_ads(mem_ctx, mods, - dsspooler_ctr.values[i]); + uint32 num_values = regval_ctr_numvals( dsspooler_ctr ); + + for (i=0; ivalues[i]); + } } ads_mod_str(mem_ctx, mods, SPOOL_REG_PRINTERNAME, printer); - if (got_dsdriver) regval_ctr_destroy(&dsdriver_ctr); - if (got_dsspooler) regval_ctr_destroy(&dsspooler_ctr); + TALLOC_FREE( dsdriver_ctr ); + TALLOC_FREE( dsspooler_ctr ); + cli_spoolss_close_printer(cli, mem_ctx, &pol); return result; @@ -328,9 +335,9 @@ BOOL get_local_printer_publishing_data(TALLOC_CTX *mem_ctx, uint32 key,val; for (key=0; key < data->num_keys; key++) { - REGVAL_CTR ctr = data->keys[key].values; - for (val=0; val < ctr.num_values; val++) - map_regval_to_ads(mem_ctx, mods, ctr.values[val]); + REGVAL_CTR *ctr = data->keys[key].values; + for (val=0; val < ctr->num_values; val++) + map_regval_to_ads(mem_ctx, mods, ctr->values[val]); } return True; } -- cgit From 8c072021efba737539b46e993df0c21a6438a82a Mon Sep 17 00:00:00 2001 From: James Peach Date: Tue, 30 Aug 2005 06:41:32 +0000 Subject: r9780: Clean up a bunch of compiler warnings. (This used to be commit 623d2e69319ffead31a780a4d6156dae45f386d7) --- source3/libads/krb5_setpw.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index dadce2593c..c261d15c21 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -317,23 +317,17 @@ static krb5_error_code parse_setpw_reply(krb5_context context, switch(res_code) { case KRB5_KPASSWD_ACCESSDENIED: return KRB5KDC_ERR_BADOPTION; - break; case KRB5_KPASSWD_INITIAL_FLAG_NEEDED: return KRB5KDC_ERR_BADOPTION; /* return KV5M_ALT_METHOD; MIT-only define */ - break; case KRB5_KPASSWD_ETYPE_NOSUPP: return KRB5KDC_ERR_ETYPE_NOSUPP; - break; case KRB5_KPASSWD_BAD_PRINCIPAL: return KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN; - break; case KRB5_KPASSWD_POLICY_REJECT: return KRB5KDC_ERR_POLICY; - break; default: return KRB5KRB_ERR_GENERIC; - break; } } } -- cgit From b552c44b79e823011991feff0c55e8a7a9a93f8a Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 13 Sep 2005 21:26:25 +0000 Subject: r10211: Fix another memleak (this time in the kerberos keytab code) Guenther (This used to be commit 9796bf45895681fee243ca8fd8297ff270c7547c) --- source3/libads/kerberos_verify.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index d6cca79318..d0dcdc5e00 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -128,7 +128,11 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut ZERO_STRUCT(kt_cursor); out: - + + for (i = 0; i < sizeof(valid_princ_formats) / sizeof(valid_princ_formats[0]); i++) { + SAFE_FREE(valid_princ_formats[i]); + } + if (!auth_ok) { if (!number_matched_principals) { DEBUG(3, ("ads_keytab_verify_ticket: no keytab principals matched expected file service name.\n")); -- cgit From eb93fc968daa42bc87cb7f5bb62ed65624a4c774 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 17 Sep 2005 00:44:34 +0000 Subject: r10285: Doh ! Guenther spotted this stupid cut-n-paste bug... Thanks Guenther ! Jeremy. (This used to be commit 7335440e480599a6e16780976ab36651a6fb969d) --- source3/libads/kerberos_verify.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index d0dcdc5e00..770d129e5d 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -86,7 +86,6 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut goto out; } - ret = krb5_kt_start_seq_get(context, keytab, &kt_cursor); if (ret != KRB5_KT_END && ret != ENOENT ) { while (!auth_ok && (krb5_kt_next_entry(context, keytab, &kt_entry, &kt_cursor) == 0)) { ret = krb5_unparse_name(context, kt_entry.principal, &entry_princ_s); -- cgit From 54abd2aa66069e6baf7769c496f46d9dba18db39 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 30 Sep 2005 17:13:37 +0000 Subject: r10656: BIG merge from trunk. Features not copied over * \PIPE\unixinfo * winbindd's {group,alias}membership new functions * winbindd's lookupsids() functionality * swat (trunk changes to be reverted as per discussion with Deryck) (This used to be commit 939c3cb5d78e3a2236209b296aa8aba8bdce32d3) --- source3/libads/authdata.c | 478 ++++++++++++++++++++++++++++++++------- source3/libads/kerberos_verify.c | 94 ++++++-- source3/libads/ldap.c | 4 +- source3/libads/ldap_printer.c | 14 +- source3/libads/sasl.c | 2 +- 5 files changed, 483 insertions(+), 109 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c index 2cc6c6ebae..2e7866c055 100644 --- a/source3/libads/authdata.c +++ b/source3/libads/authdata.c @@ -2,6 +2,11 @@ Unix SMB/CIFS implementation. kerberos authorization data (PAC) utility library Copyright (C) Jim McDonough 2003 + Copyright (C) Andrew Bartlett 2004-2005 + Copyright (C) Andrew Tridgell 2001 + Copyright (C) Luke Howard 2002-2003 + Copyright (C) Stefan Metzmacher 2004-2005 + Copyright (C) Guenther Deschner 2005 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -22,27 +27,6 @@ #ifdef HAVE_KRB5 -static DATA_BLOB unwrap_pac(DATA_BLOB *auth_data) -{ - DATA_BLOB pac_contents; - ASN1_DATA data; - int data_type; - - asn1_load(&data, *auth_data); - asn1_start_tag(&data, ASN1_SEQUENCE(0)); - asn1_start_tag(&data, ASN1_SEQUENCE(0)); - asn1_start_tag(&data, ASN1_CONTEXT(0)); - asn1_read_Integer(&data, &data_type); - asn1_end_tag(&data); - asn1_start_tag(&data, ASN1_CONTEXT(1)); - asn1_read_OctetString(&data, &pac_contents); - asn1_end_tag(&data); - asn1_end_tag(&data); - asn1_end_tag(&data); - asn1_free(&data); - return pac_contents; -} - static BOOL pac_io_logon_name(const char *desc, PAC_LOGON_NAME *logon_name, prs_struct *ps, int depth) { @@ -75,6 +59,8 @@ static BOOL pac_io_logon_name(const char *desc, PAC_LOGON_NAME *logon_name, } + +#if 0 /* Unused (handled now in net_io_user_info3()) - Guenther */ static BOOL pac_io_krb_sids(const char *desc, KRB_SID_AND_ATTRS *sid_and_attr, prs_struct *ps, int depth) { @@ -159,6 +145,7 @@ static BOOL pac_io_krb_sid_and_attr_array(const char *desc, return True; } +#endif static BOOL pac_io_group_membership(const char *desc, GROUP_MEMBERSHIP *membership, @@ -216,27 +203,34 @@ static BOOL pac_io_group_membership_array(const char *desc, } +#if 0 /* Unused, replaced using an expanded net_io_user_info3() now - Guenther */ static BOOL pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info, prs_struct *ps, int depth) { - uint32 garbage; + uint32 garbage, i; + if (NULL == info) return False; prs_debug(ps, depth, desc, "pac_io_pac_logon_info"); depth++; - if (!prs_uint32("unknown", ps, depth, &garbage)) + if (!prs_align(ps)) return False; - if (!prs_uint32("unknown", ps, depth, &garbage)) + if (!prs_uint32("unknown", ps, depth, &garbage)) /* 00081001 */ + return False; + if (!prs_uint32("unknown", ps, depth, &garbage)) /* cccccccc */ return False; if (!prs_uint32("bufferlen", ps, depth, &garbage)) return False; - if (!prs_uint32("bufferlenhi", ps, depth, &garbage)) + if (!prs_uint32("bufferlenhi", ps, depth, &garbage)) /* 00000000 */ return False; + if (!prs_uint32("pointer", ps, depth, &garbage)) return False; + if (!prs_align(ps)) + return False; if (!smb_io_time("logon_time", &info->logon_time, ps, depth)) return False; if (!smb_io_time("logoff_time", &info->logoff_time, ps, depth)) @@ -270,7 +264,7 @@ static BOOL pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info, if (!prs_uint16("logon_count", ps, depth, &info->logon_count)) return False; - if (!prs_uint16("reserved12", ps, depth, &info->reserved12)) + if (!prs_uint16("bad_password_count", ps, depth, &info->bad_password_count)) return False; if (!prs_uint32("user_rid", ps, depth, &info->user_rid)) return False; @@ -287,13 +281,7 @@ static BOOL pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info, if (!prs_uint32("user_flags", ps, depth, &info->user_flags)) return False; - if (!prs_uint32("reserved13.0", ps, depth, &info->reserved13[0])) - return False; - if (!prs_uint32("reserved13.1", ps, depth, &info->reserved13[1])) - return False; - if (!prs_uint32("reserved13.2", ps, depth, &info->reserved13[2])) - return False; - if (!prs_uint32("reserved13.3", ps, depth, &info->reserved13[3])) + if (!prs_uint8s(False, "session_key", ps, depth, info->session_key, 16)) return False; if (!smb_io_unihdr("hdr_dom_controller", @@ -306,30 +294,17 @@ static BOOL pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info, if (!prs_uint32("ptr_dom_sid", ps, depth, &info->ptr_dom_sid)) return False; - if (!prs_uint32("reserved16.0", ps, depth, &info->reserved16[0])) - return False; - if (!prs_uint32("reserved16.1", ps, depth, &info->reserved16[1])) + if (!prs_uint8s(False, "lm_session_key", ps, depth, info->lm_session_key, 8)) return False; - /* might be acb_info */ - if (!prs_uint32("reserved17", ps, depth, &info->reserved17)) + if (!prs_uint32("acct_flags", ps, depth, &info->acct_flags)) return False; - - if (!prs_uint32("reserved18.0", ps, depth, &info->reserved18[0])) - return False; - if (!prs_uint32("reserved18.1", ps, depth, &info->reserved18[1])) - return False; - if (!prs_uint32("reserved18.2", ps, depth, &info->reserved18[2])) - return False; - if (!prs_uint32("reserved18.3", ps, depth, &info->reserved18[3])) - return False; - if (!prs_uint32("reserved18.4", ps, depth, &info->reserved18[4])) - return False; - if (!prs_uint32("reserved18.5", ps, depth, &info->reserved18[5])) - return False; - if (!prs_uint32("reserved18.6", ps, depth, &info->reserved18[6])) - return False; + for (i = 0; i < 7; i++) + { + if (!prs_uint32("unkown", ps, depth, &info->unknown[i])) /* unknown */ + return False; + } if (!prs_uint32("sid_count", ps, depth, &info->sid_count)) return False; @@ -395,44 +370,109 @@ static BOOL pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info, &info->res_group_dom_sid, ps, depth)) return False; - if (info->ptr_res_groups) + if (info->ptr_res_groups) { + + if (!(info->user_flgs & LOGON_RESOURCE_GROUPS)) { + DEBUG(0,("user_flgs attribute does not have LOGON_RESOURCE_GROUPS\n")); + /* return False; */ + } + if (!pac_io_group_membership_array("res group membership", &info->res_groups, info->res_group_count, ps, depth)) return False; + } + + return True; +} +#endif + +static BOOL pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info, + prs_struct *ps, int depth) +{ + uint32 garbage; + BOOL kerb_validation_info = True; + + if (NULL == info) + return False; + + prs_debug(ps, depth, desc, "pac_io_pac_logon_info"); + depth++; + + if (!prs_align(ps)) + return False; + if (!prs_uint32("unknown", ps, depth, &garbage)) /* 00081001 */ + return False; + if (!prs_uint32("unknown", ps, depth, &garbage)) /* cccccccc */ + return False; + if (!prs_uint32("bufferlen", ps, depth, &garbage)) + return False; + if (!prs_uint32("bufferlenhi", ps, depth, &garbage)) /* 00000000 */ + return False; + + if(!net_io_user_info3("", &info->info3, ps, depth, 3, kerb_validation_info)) + return False; + + if (info->info3.ptr_res_group_dom_sid) { + if (!smb_io_dom_sid2("res_group_dom_sid", + &info->res_group_dom_sid, ps, depth)) + return False; + } + + if (info->info3.ptr_res_groups) { + + if (!(info->info3.user_flgs & LOGON_RESOURCE_GROUPS)) { + DEBUG(0,("user_flgs attribute does not have LOGON_RESOURCE_GROUPS\n")); + /* return False; */ + } + + if (!pac_io_group_membership_array("res group membership", + &info->res_groups, + info->info3.res_group_count, + ps, depth)) + return False; + } return True; } + static BOOL pac_io_pac_signature_data(const char *desc, PAC_SIGNATURE_DATA *data, uint32 length, prs_struct *ps, int depth) { uint32 siglen = length - sizeof(uint32); - if (NULL == data) - return False; - prs_debug(ps, depth, desc, "pac_io_pac_signature_data"); depth++; + + if (data == NULL) + return False; + if (!prs_align(ps)) + return False; if (!prs_uint32("type", ps, depth, &data->type)) return False; - if (UNMARSHALLING(ps)) { - data->signature = PRS_ALLOC_MEM(ps, unsigned char, siglen); - if (!data->signature) { + + if (UNMARSHALLING(ps) && length) { + data->signature.buffer = PRS_ALLOC_MEM(ps, uint8, siglen); + if (!data->signature.buffer) { DEBUG(3, ("No memory available\n")); return False; } } - if (!prs_uint8s(False, "signature", ps, depth, data->signature,siglen)) + + data->signature.buf_len = siglen; + + if (!prs_uint8s(False, "signature", ps, depth, data->signature.buffer, data->signature.buf_len)) return False; + return True; } -static BOOL pac_io_pac_info_hdr_ctr(const char *desc, PAC_INFO_HDR *hdr, +static BOOL pac_io_pac_info_hdr_ctr(const char *desc, PAC_BUFFER *hdr, prs_struct *ps, int depth) { if (NULL == hdr) @@ -445,8 +485,8 @@ static BOOL pac_io_pac_info_hdr_ctr(const char *desc, PAC_INFO_HDR *hdr, return False; if (hdr->offset != prs_offset(ps)) { - DEBUG(5, ("offset in header(x%x) and data(x%x) do not match\n", - hdr->offset, prs_offset(ps))); + DEBUG(5,("offset in header(x%x) and data(x%x) do not match, correcting\n", + hdr->offset, prs_offset(ps))); prs_set_offset(ps, hdr->offset); } @@ -518,10 +558,15 @@ static BOOL pac_io_pac_info_hdr_ctr(const char *desc, PAC_INFO_HDR *hdr, prs_set_offset(ps, prs_offset(ps) + hdr->size); } +#if 0 + /* obscure pad */ + if (!prs_uint32("pad", ps, depth, &hdr->pad)) + return False; +#endif return True; } -static BOOL pac_io_pac_info_hdr(const char *desc, PAC_INFO_HDR *hdr, +static BOOL pac_io_pac_info_hdr(const char *desc, PAC_BUFFER *hdr, prs_struct *ps, int depth) { if (NULL == hdr) @@ -563,19 +608,19 @@ static BOOL pac_io_pac_data(const char *desc, PAC_DATA *data, return False; if (UNMARSHALLING(ps) && data->num_buffers > 0) { - if ((data->pac_info_hdr_ptr = PRS_ALLOC_MEM(ps, PAC_INFO_HDR, data->num_buffers)) == NULL) { + if ((data->pac_buffer = PRS_ALLOC_MEM(ps, PAC_BUFFER, data->num_buffers)) == NULL) { return False; } } for (i=0; inum_buffers; i++) { - if (!pac_io_pac_info_hdr(desc, &data->pac_info_hdr_ptr[i], ps, + if (!pac_io_pac_info_hdr(desc, &data->pac_buffer[i], ps, depth)) return False; } for (i=0; inum_buffers; i++) { - if (!pac_io_pac_info_hdr_ctr(desc, &data->pac_info_hdr_ptr[i], + if (!pac_io_pac_info_hdr_ctr(desc, &data->pac_buffer[i], ps, depth)) return False; } @@ -583,25 +628,300 @@ static BOOL pac_io_pac_data(const char *desc, PAC_DATA *data, return True; } -PAC_DATA *decode_pac_data(DATA_BLOB *auth_data, TALLOC_CTX *ctx) +static NTSTATUS check_pac_checksum(TALLOC_CTX *mem_ctx, + DATA_BLOB pac_data, + PAC_SIGNATURE_DATA *sig, + krb5_context context, + krb5_keyblock *keyblock) +{ + krb5_error_code ret; + krb5_checksum cksum; + krb5_keyusage usage = 0; + + smb_krb5_checksum_from_pac_sig(&cksum, sig); + +#ifdef HAVE_KRB5_KU_OTHER_CKSUM /* Heimdal */ + usage = KRB5_KU_OTHER_CKSUM; +#elif defined(HAVE_KRB5_KEYUSAGE_APP_DATA_CKSUM) /* MIT */ + usage = KRB5_KEYUSAGE_APP_DATA_CKSUM; +#else +#error UNKNOWN_KRB5_KEYUSAGE +#endif + + ret = smb_krb5_verify_checksum(context, + keyblock, + usage, + &cksum, + pac_data.data, + pac_data.length); + + if (ret) { + DEBUG(2,("check_pac_checksum: PAC Verification failed: %s (%d)\n", + error_message(ret), ret)); + return NT_STATUS_ACCESS_DENIED; + } + + return NT_STATUS_OK; +} + +static NTSTATUS parse_pac_data(TALLOC_CTX *mem_ctx, DATA_BLOB *pac_data_blob, PAC_DATA *pac_data) { - DATA_BLOB pac_data_blob = unwrap_pac(auth_data); prs_struct ps; - PAC_DATA *pac_data; + PAC_DATA *my_pac; - DEBUG(5,("dump_pac_data\n")); - prs_init(&ps, pac_data_blob.length, ctx, UNMARSHALL); - prs_copy_data_in(&ps, (char *)pac_data_blob.data, pac_data_blob.length); - prs_set_offset(&ps, 0); + if (!prs_init(&ps, pac_data_blob->length, mem_ctx, UNMARSHALL)) + return NT_STATUS_NO_MEMORY; - data_blob_free(&pac_data_blob); + if (!prs_copy_data_in(&ps, (char *)pac_data_blob->data, pac_data_blob->length)) + return NT_STATUS_INVALID_PARAMETER; + + prs_set_offset(&ps, 0); - pac_data = TALLOC_ZERO_P(ctx, PAC_DATA); - pac_io_pac_data("pac data", pac_data, &ps, 0); + my_pac = TALLOC_ZERO_P(mem_ctx, PAC_DATA); + if (!pac_io_pac_data("pac data", my_pac, &ps, 0)) + return NT_STATUS_INVALID_PARAMETER; prs_mem_free(&ps); - return pac_data; + *pac_data = *my_pac; + + return NT_STATUS_OK; +} + +/* just for debugging, will be removed later - Guenther */ +char *pac_group_attr_string(uint32 attr) +{ + fstring name = ""; + + if (!attr) + return NULL; + + if (attr & SE_GROUP_MANDATORY) fstrcat(name, "SE_GROUP_MANDATORY "); + if (attr & SE_GROUP_ENABLED_BY_DEFAULT) fstrcat(name, "SE_GROUP_ENABLED_BY_DEFAULT "); + if (attr & SE_GROUP_ENABLED) fstrcat(name, "SE_GROUP_ENABLED "); + if (attr & SE_GROUP_OWNER) fstrcat(name, "SE_GROUP_OWNER "); + if (attr & SE_GROUP_USE_FOR_DENY_ONLY) fstrcat(name, "SE_GROUP_USE_FOR_DENY_ONLY "); + if (attr & SE_GROUP_LOGON_ID) fstrcat(name, "SE_GROUP_LOGON_ID "); + if (attr & SE_GROUP_RESOURCE) fstrcat(name, "SE_GROUP_RESOURCE "); + + return SMB_STRDUP(name); +} + +/* just for debugging, will be removed later - Guenther */ +static void dump_pac_logon_info(PAC_LOGON_INFO *logon_info) { + + DOM_SID dom_sid, res_group_dom_sid; + int i; + char *attr_string; + uint32 user_flgs = logon_info->info3.user_flgs; + + if (logon_info->info3.ptr_res_group_dom_sid) { + sid_copy(&res_group_dom_sid, &logon_info->res_group_dom_sid.sid); + } + sid_copy(&dom_sid, &logon_info->info3.dom_sid.sid); + + DEBUG(10,("The PAC:\n")); + + DEBUGADD(10,("\tUser Flags: 0x%x (%d)\n", user_flgs, user_flgs)); + if (user_flgs & LOGON_EXTRA_SIDS) + DEBUGADD(10,("\tUser Flags: LOGON_EXTRA_SIDS 0x%x (%d)\n", LOGON_EXTRA_SIDS, LOGON_EXTRA_SIDS)); + if (user_flgs & LOGON_RESOURCE_GROUPS) + DEBUGADD(10,("\tUser Flags: LOGON_RESOURCE_GROUPS 0x%x (%d)\n", LOGON_RESOURCE_GROUPS, LOGON_RESOURCE_GROUPS)); + DEBUGADD(10,("\tUser SID: %s-%d\n", sid_string_static(&dom_sid), logon_info->info3.user_rid)); + DEBUGADD(10,("\tGroup SID: %s-%d\n", sid_string_static(&dom_sid), logon_info->info3.group_rid)); + + DEBUGADD(10,("\tGroup Membership (Global and Universal Groups of own domain):\n")); + for (i = 0; i < logon_info->info3.num_groups; i++) { + attr_string = pac_group_attr_string(logon_info->info3.gids[i].attr); + DEBUGADD(10,("\t\t%d: sid: %s-%d\n\t\t attr: 0x%x == %s\n", + i, sid_string_static(&dom_sid), + logon_info->info3.gids[i].g_rid, + logon_info->info3.gids[i].attr, + attr_string)); + SAFE_FREE(attr_string); + } + + DEBUGADD(10,("\tGroup Membership (Domain Local Groups and Groups from Trusted Domains):\n")); + for (i = 0; i < logon_info->info3.num_other_sids; i++) { + attr_string = pac_group_attr_string(logon_info->info3.other_sids_attrib[i]); + DEBUGADD(10,("\t\t%d: sid: %s\n\t\t attr: 0x%x == %s\n", + i, sid_string_static(&logon_info->info3.other_sids[i].sid), + logon_info->info3.other_sids_attrib[i], + attr_string)); + SAFE_FREE(attr_string); + } + + DEBUGADD(10,("\tGroup Membership (Ressource Groups (SID History ?)):\n")); + for (i = 0; i < logon_info->info3.res_group_count; i++) { + attr_string = pac_group_attr_string(logon_info->res_groups.group_membership[i].attrs); + DEBUGADD(10,("\t\t%d: sid: %s-%d\n\t\t attr: 0x%x == %s\n", + i, sid_string_static(&res_group_dom_sid), + logon_info->res_groups.group_membership[i].rid, + logon_info->res_groups.group_membership[i].attrs, + attr_string)); + SAFE_FREE(attr_string); + } +} + +NTSTATUS decode_pac_data(TALLOC_CTX *mem_ctx, + DATA_BLOB *pac_data_blob, + krb5_context context, + krb5_keyblock *service_keyblock, + krb5_const_principal client_principal, + time_t tgs_authtime, + PAC_DATA **pac_data) + +{ + DATA_BLOB modified_pac_blob; + PAC_DATA *my_pac; + NTSTATUS nt_status; + krb5_error_code ret; + PAC_SIGNATURE_DATA *srv_sig = NULL; + PAC_SIGNATURE_DATA *kdc_sig = NULL; + PAC_LOGON_NAME *logon_name = NULL; + PAC_LOGON_INFO *logon_info = NULL; + krb5_principal client_principal_pac; + NTTIME tgs_authtime_nttime; + int i, srv_sig_pos = 0, kdc_sig_pos = 0; + fstring username; + + *pac_data = NULL; + + my_pac = talloc(mem_ctx, PAC_DATA); + if (!my_pac) { + return NT_STATUS_NO_MEMORY; + } + + nt_status = parse_pac_data(mem_ctx, pac_data_blob, my_pac); + if (!NT_STATUS_IS_OK(nt_status)) { + DEBUG(0,("decode_pac_data: failed to parse PAC\n")); + return nt_status; + } + + modified_pac_blob = data_blob_talloc(mem_ctx, pac_data_blob->data, pac_data_blob->length); + + if (my_pac->num_buffers < 4) { + nt_status = NT_STATUS_INVALID_PARAMETER; + goto out; + } + + /* store signatures */ + for (i=0; i < my_pac->num_buffers; i++) { + + switch (my_pac->pac_buffer[i].type) { + + case PAC_TYPE_SERVER_CHECKSUM: + if (!my_pac->pac_buffer[i].ctr->pac.srv_cksum) { + break; + } + + srv_sig = my_pac->pac_buffer[i].ctr->pac.srv_cksum; + + /* get position of signature buffer */ + srv_sig_pos = my_pac->pac_buffer[i].offset; + srv_sig_pos += sizeof(uint32); + + break; + + case PAC_TYPE_PRIVSVR_CHECKSUM: + if (!my_pac->pac_buffer[i].ctr->pac.privsrv_cksum) { + break; + } + + kdc_sig = my_pac->pac_buffer[i].ctr->pac.privsrv_cksum; + + /* get position of signature buffer */ + kdc_sig_pos = my_pac->pac_buffer[i].offset; + kdc_sig_pos += sizeof(uint32); + + break; + + case PAC_TYPE_LOGON_NAME: + if (!my_pac->pac_buffer[i].ctr->pac.logon_name) { + break; + } + + logon_name = my_pac->pac_buffer[i].ctr->pac.logon_name; + break; + + case PAC_TYPE_LOGON_INFO: + if (!my_pac->pac_buffer[i].ctr->pac.logon_info) { + break; + } + + logon_info = my_pac->pac_buffer[i].ctr->pac.logon_info; + break; + } + + } + + if (!srv_sig || !kdc_sig || !logon_name || !logon_info) { + nt_status = NT_STATUS_INVALID_PARAMETER; + goto out; + } + + /* zero PAC_SIGNATURE_DATA signature buffer */ + memset(&modified_pac_blob.data[srv_sig_pos], '\0', srv_sig->signature.buf_len); + memset(&modified_pac_blob.data[kdc_sig_pos], '\0', kdc_sig->signature.buf_len); + + /* check server signature */ + nt_status = check_pac_checksum(mem_ctx, modified_pac_blob, srv_sig, context, service_keyblock); + if (!NT_STATUS_IS_OK(nt_status)) { + DEBUG(0,("decode_pac_data: failed to verify PAC server signature\n")); + goto out; + } + + /* Convert to NT time, so as not to loose accuracy in comparison */ + unix_to_nt_time(&tgs_authtime_nttime, tgs_authtime); + + if (!nt_time_equals(&tgs_authtime_nttime, &logon_name->logon_time)) { + + DEBUG(2,("decode_pac_data: Logon time mismatch between ticket and PAC!\n")); + DEBUGADD(2, ("decode_pac_data: PAC: %s\n", + http_timestring(nt_time_to_unix(&logon_name->logon_time)))); + DEBUGADD(2, ("decode_pac_data: Ticket: %s\n", + http_timestring(nt_time_to_unix(&tgs_authtime_nttime)))); + + nt_status = NT_STATUS_ACCESS_DENIED; + goto out; + } + + if (!logon_name->len) { + DEBUG(2,("decode_pac_data: No Logon Name available\n")); + nt_status = NT_STATUS_INVALID_PARAMETER; + goto out; + } + rpcstr_pull(username, logon_name->username, sizeof(username), -1, STR_TERMINATE); + + ret = smb_krb5_parse_name_norealm(context, username, &client_principal_pac); + if (ret) { + DEBUG(2,("decode_pac_data: Could not parse name from incoming PAC: [%s]: %s\n", + username, error_message(ret))); + nt_status = NT_STATUS_INVALID_PARAMETER; + goto out; + } + + if (!smb_krb5_principal_compare_any_realm(context, client_principal, client_principal_pac)) { + DEBUG(2,("decode_pac_data: Name in PAC [%s] does not match principal name in ticket\n", + username)); + nt_status = NT_STATUS_ACCESS_DENIED; + goto out; + } + + DEBUG(10,("Successfully validated Kerberos PAC\n")); + + dump_pac_logon_info(logon_info); + + *pac_data = my_pac; + + nt_status = NT_STATUS_OK; + +out: + if (client_principal_pac) { + krb5_free_principal(context, client_principal_pac); + } + + return nt_status; } #endif diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 770d129e5d..6a5c6b6a49 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -4,8 +4,9 @@ Copyright (C) Andrew Tridgell 2001 Copyright (C) Remus Koos 2001 Copyright (C) Luke Howard 2003 - Copyright (C) Guenther Deschner 2003 + Copyright (C) Guenther Deschner 2003, 2005 Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003 + Copyright (C) Andrew Bartlett 2004-2005 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -37,7 +38,8 @@ const krb5_data *krb5_princ_component(krb5_context, krb5_principal, int ); ***********************************************************************************/ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context auth_context, - const DATA_BLOB *ticket, krb5_data *p_packet, krb5_ticket **pp_tkt) + const DATA_BLOB *ticket, krb5_data *p_packet, krb5_ticket **pp_tkt, + krb5_keyblock **keyblock) { krb5_error_code ret = 0; BOOL auth_ok = False; @@ -100,12 +102,18 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut p_packet->length = ticket->length; p_packet->data = (krb5_pointer)ticket->data; *pp_tkt = NULL; - ret = krb5_rd_req(context, &auth_context, p_packet, kt_entry.principal, keytab, NULL, pp_tkt); + + ret = krb5_rd_req_return_keyblock_from_keytab(context, &auth_context, p_packet, + kt_entry.principal, keytab, + NULL, pp_tkt, keyblock); + if (ret) { - DEBUG(10, ("ads_keytab_verify_ticket: krb5_rd_req(%s) failed: %s\n", + DEBUG(10,("ads_keytab_verify_ticket: " + "krb5_rd_req_return_keyblock_from_keytab(%s) failed: %s\n", entry_princ_s, error_message(ret))); } else { - DEBUG(3,("ads_keytab_verify_ticket: krb5_rd_req succeeded for principal %s\n", + DEBUG(3,("ads_keytab_verify_ticket: " + "krb5_rd_req_return_keyblock_from_keytab succeeded for principal %s\n", entry_princ_s)); auth_ok = True; break; @@ -172,8 +180,9 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut ***********************************************************************************/ static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context auth_context, - krb5_principal host_princ, - const DATA_BLOB *ticket, krb5_data *p_packet, krb5_ticket **pp_tkt) + krb5_principal host_princ, + const DATA_BLOB *ticket, krb5_data *p_packet, krb5_ticket **pp_tkt, + krb5_keyblock **keyblock) { krb5_error_code ret = 0; BOOL auth_ok = False; @@ -182,6 +191,8 @@ static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context au krb5_enctype *enctypes = NULL; int i; + ZERO_STRUCTP(keyblock); + if (!secrets_init()) { DEBUG(1,("ads_secrets_verify_ticket: secrets_init failed\n")); return False; @@ -222,20 +233,23 @@ static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context au krb5_auth_con_setuseruserkey(context, auth_context, key); - krb5_free_keyblock(context, key); - if (!(ret = krb5_rd_req(context, &auth_context, p_packet, NULL, NULL, NULL, pp_tkt))) { DEBUG(10,("ads_secrets_verify_ticket: enc type [%u] decrypted message !\n", (unsigned int)enctypes[i] )); auth_ok = True; + krb5_copy_keyblock(context, key, keyblock); + krb5_free_keyblock(context, key); break; } DEBUG((ret != KRB5_BAD_ENCTYPE) ? 3 : 10, ("ads_secrets_verify_ticket: enc type [%u] failed to decrypt with error %s\n", (unsigned int)enctypes[i], error_message(ret))); + + krb5_free_keyblock(context, key); + } out: @@ -251,27 +265,33 @@ static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context au authorization_data if available. ***********************************************************************************/ -NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, - char **principal, DATA_BLOB *auth_data, +NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, + const char *realm, const DATA_BLOB *ticket, + char **principal, PAC_DATA **pac_data, DATA_BLOB *ap_rep, DATA_BLOB *session_key) { NTSTATUS sret = NT_STATUS_LOGON_FAILURE; + DATA_BLOB auth_data; krb5_context context = NULL; krb5_auth_context auth_context = NULL; krb5_data packet; krb5_ticket *tkt = NULL; krb5_rcache rcache = NULL; + krb5_keyblock *keyblock = NULL; + time_t authtime; int ret; krb5_principal host_princ = NULL; + krb5_const_principal client_principal = NULL; char *host_princ_s = NULL; BOOL got_replay_mutex = False; BOOL auth_ok = False; + BOOL got_auth_data = False; ZERO_STRUCT(packet); - ZERO_STRUCTP(auth_data); + ZERO_STRUCT(auth_data); ZERO_STRUCTP(ap_rep); ZERO_STRUCTP(session_key); @@ -335,20 +355,30 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, } if (lp_use_kerberos_keytab()) { - auth_ok = ads_keytab_verify_ticket(context, auth_context, ticket, &packet, &tkt); + auth_ok = ads_keytab_verify_ticket(context, auth_context, ticket, &packet, &tkt, &keyblock); } if (!auth_ok) { auth_ok = ads_secrets_verify_ticket(context, auth_context, host_princ, - ticket, &packet, &tkt); + ticket, &packet, &tkt, &keyblock); } release_server_mutex(); got_replay_mutex = False; +#if 0 + /* Heimdal leaks here, if we fix the leak, MIT crashes */ + if (rcache) { + krb5_rc_close(context, rcache); + } +#endif + if (!auth_ok) { DEBUG(3,("ads_verify_ticket: krb5_rd_req with auth failed (%s)\n", error_message(ret))); goto out; + } else { + authtime = get_authtime_from_tkt(tkt); + client_principal = get_principal_from_tkt(tkt); } ret = krb5_mk_rep(context, auth_context, &packet); @@ -369,20 +399,40 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, file_save("/tmp/ticket.dat", ticket->data, ticket->length); #endif - get_auth_data_from_tkt(auth_data, tkt); + /* continue when no PAC is retrieved + (like accounts that have the UF_NO_AUTH_DATA_REQUIRED flag set) */ - { - TALLOC_CTX *ctx = talloc_init("pac data"); - decode_pac_data(auth_data, ctx); - talloc_destroy(ctx); + got_auth_data = get_auth_data_from_tkt(mem_ctx, &auth_data, tkt); + if (!got_auth_data) { + DEBUG(3,("ads_verify_ticket: did not retrieve auth data. continuing without PAC\n")); + } + + if (got_auth_data && pac_data != NULL) { + + sret = decode_pac_data(mem_ctx, &auth_data, context, keyblock, client_principal, authtime, pac_data); + if (!NT_STATUS_IS_OK(sret)) { + DEBUG(0,("ads_verify_ticket: failed to decode PAC_DATA: %s\n", nt_errstr(sret))); + goto out; + } + data_blob_free(&auth_data); } #if 0 +#if defined(HAVE_KRB5_TKT_ENC_PART2) + /* MIT */ if (tkt->enc_part2) { file_save("/tmp/authdata.dat", tkt->enc_part2->authorization_data[0]->contents, tkt->enc_part2->authorization_data[0]->length); } +#else + /* Heimdal */ + if (tkt->ticket.authorization_data) { + file_save("/tmp/authdata.dat", + tkt->ticket.authorization_data->val->ad_data.data, + tkt->ticket.authorization_data->val->ad_data.length); + } +#endif #endif if ((ret = krb5_unparse_name(context, get_principal_from_tkt(tkt), @@ -402,7 +452,7 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, } if (!NT_STATUS_IS_OK(sret)) { - data_blob_free(auth_data); + data_blob_free(&auth_data); } if (!NT_STATUS_IS_OK(sret)) { @@ -413,6 +463,10 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, krb5_free_principal(context, host_princ); } + if (keyblock) { + krb5_free_keyblock(context, keyblock); + } + if (tkt != NULL) { krb5_free_ticket(context, tkt); } diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 81afd7f49e..bf402b3499 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2104,7 +2104,7 @@ char **ads_pull_strings_range(ADS_STRUCT *ads, if ((*num_strings) != range_start) { DEBUG(1, ("ads_pull_strings_range: Range attribute (%s) doesn't start at %u, but at %lu" " - aborting range retreival\n", - range_attr, *num_strings + 1, range_start)); + range_attr, (unsigned int)(*num_strings) + 1, range_start)); ldap_memfree(range_attr); *more_strings = False; return NULL; @@ -2140,7 +2140,7 @@ char **ads_pull_strings_range(ADS_STRUCT *ads, *next_attribute = talloc_asprintf(mem_ctx, "%s;range=%d-*", field, - *num_strings); + (int)*num_strings); if (!*next_attribute) { DEBUG(1, ("talloc_asprintf for next attribute failed!\n")); diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index db544fe209..d6ac09d22b 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -258,7 +258,7 @@ static void map_regval_to_ads(TALLOC_CTX *ctx, ADS_MODLIST *mods, } -WERROR get_remote_printer_publishing_data(struct cli_state *cli, +WERROR get_remote_printer_publishing_data(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, ADS_MODLIST *mods, const char *printer) @@ -269,16 +269,16 @@ WERROR get_remote_printer_publishing_data(struct cli_state *cli, uint32 i; POLICY_HND pol; - asprintf(&servername, "\\\\%s", cli->desthost); + asprintf(&servername, "\\\\%s", cli->cli->desthost); asprintf(&printername, "%s\\%s", servername, printer); if (!servername || !printername) { DEBUG(3, ("Insufficient memory\n")); return WERR_NOMEM; } - result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, + result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS, - servername, cli->user_name, &pol); + servername, cli->cli->user_name, &pol); if (!W_ERROR_IS_OK(result)) { DEBUG(3, ("Unable to open printer %s, error is %s.\n", printername, dos_errstr(result))); @@ -288,7 +288,7 @@ WERROR get_remote_printer_publishing_data(struct cli_state *cli, if ( !(dsdriver_ctr = TALLOC_ZERO_P( mem_ctx, REGVAL_CTR )) ) return WERR_NOMEM; - result = cli_spoolss_enumprinterdataex(cli, mem_ctx, &pol, SPOOL_DSDRIVER_KEY, dsdriver_ctr); + result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx, &pol, SPOOL_DSDRIVER_KEY, dsdriver_ctr); if (!W_ERROR_IS_OK(result)) { DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n", @@ -305,7 +305,7 @@ WERROR get_remote_printer_publishing_data(struct cli_state *cli, if ( !(dsspooler_ctr = TALLOC_ZERO_P( mem_ctx, REGVAL_CTR )) ) return WERR_NOMEM; - result = cli_spoolss_enumprinterdataex(cli, mem_ctx, &pol, SPOOL_DSSPOOLER_KEY, dsspooler_ctr); + result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx, &pol, SPOOL_DSSPOOLER_KEY, dsspooler_ctr); if (!W_ERROR_IS_OK(result)) { DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n", @@ -323,7 +323,7 @@ WERROR get_remote_printer_publishing_data(struct cli_state *cli, TALLOC_FREE( dsdriver_ctr ); TALLOC_FREE( dsspooler_ctr ); - cli_spoolss_close_printer(cli, mem_ctx, &pol); + rpccli_spoolss_close_printer(cli, mem_ctx, &pol); return result; } diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 8fa62a5ade..72cbf7264e 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -142,7 +142,7 @@ static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *princip DATA_BLOB session_key = data_blob(NULL, 0); int rc; - rc = spnego_gen_negTokenTarg(principal, ads->auth.time_offset, &blob, &session_key); + rc = spnego_gen_negTokenTarg(principal, ads->auth.time_offset, &blob, &session_key, 0); if (rc) { return ADS_ERROR_KRB5(rc); -- cgit From aa0dff680d2ea351a0a21cb86a51cd99887237c4 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 1 Oct 2005 09:43:53 +0000 Subject: r10671: Attempt to fix the build on machines without kerberos headers. Volker (This used to be commit cb816e65a95802d5172c410d1acda2da070b871d) --- source3/libads/authdata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c index 2e7866c055..d28376c775 100644 --- a/source3/libads/authdata.c +++ b/source3/libads/authdata.c @@ -763,7 +763,7 @@ static void dump_pac_logon_info(PAC_LOGON_INFO *logon_info) { } } -NTSTATUS decode_pac_data(TALLOC_CTX *mem_ctx, + NTSTATUS decode_pac_data(TALLOC_CTX *mem_ctx, DATA_BLOB *pac_data_blob, krb5_context context, krb5_keyblock *service_keyblock, -- cgit From ebf8a843754ba02f57b38ae01bf143a242132572 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 4 Oct 2005 11:21:57 +0000 Subject: r10710: Fix uninitialized variable. (Thanks to Chengjie Liu ) Guenther (This used to be commit 241466ee650d1db1b89a4b5b640f27f6b83644c6) --- source3/libads/authdata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c index d28376c775..9fd30e9dfb 100644 --- a/source3/libads/authdata.c +++ b/source3/libads/authdata.c @@ -780,7 +780,7 @@ static void dump_pac_logon_info(PAC_LOGON_INFO *logon_info) { PAC_SIGNATURE_DATA *kdc_sig = NULL; PAC_LOGON_NAME *logon_name = NULL; PAC_LOGON_INFO *logon_info = NULL; - krb5_principal client_principal_pac; + krb5_principal client_principal_pac = NULL; NTTIME tgs_authtime_nttime; int i, srv_sig_pos = 0, kdc_sig_pos = 0; fstring username; -- cgit From 879eb0933efedd900aba336024ebfec75407d373 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 11 Oct 2005 16:27:05 +0000 Subject: r10907: Handle the case when we can't verify the PAC signature because the ticket was encrypted using a DES key (and the Windows KDC still puts CKSUMTYPE_HMAC_MD5_ARCFOUR in the PAC). In that case, return to old behaviour and ignore the PAC. Thanks to Chengjie Liu . Guenther (This used to be commit 48d8a9dd9f573d0d913a26a62e4ad3d224731343) --- source3/libads/kerberos_verify.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 6a5c6b6a49..f21577d080 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -272,6 +272,7 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, DATA_BLOB *session_key) { NTSTATUS sret = NT_STATUS_LOGON_FAILURE; + NTSTATUS pac_ret; DATA_BLOB auth_data; krb5_context context = NULL; krb5_auth_context auth_context = NULL; @@ -400,7 +401,8 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, #endif /* continue when no PAC is retrieved - (like accounts that have the UF_NO_AUTH_DATA_REQUIRED flag set) */ + (like accounts that have the UF_NO_AUTH_DATA_REQUIRED flag set, + or Kerberos tickets encryped using a DES key) - Guenther */ got_auth_data = get_auth_data_from_tkt(mem_ctx, &auth_data, tkt); if (!got_auth_data) { @@ -409,10 +411,10 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, if (got_auth_data && pac_data != NULL) { - sret = decode_pac_data(mem_ctx, &auth_data, context, keyblock, client_principal, authtime, pac_data); - if (!NT_STATUS_IS_OK(sret)) { - DEBUG(0,("ads_verify_ticket: failed to decode PAC_DATA: %s\n", nt_errstr(sret))); - goto out; + pac_ret = decode_pac_data(mem_ctx, &auth_data, context, keyblock, client_principal, authtime, pac_data); + if (!NT_STATUS_IS_OK(pac_ret)) { + DEBUG(3,("ads_verify_ticket: failed to decode PAC_DATA: %s\n", nt_errstr(pac_ret))); + *pac_data = NULL; } data_blob_free(&auth_data); } -- cgit From 8d7c88667190fe286971ac4fffb64ee5bd9eeeb0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 18 Oct 2005 03:24:00 +0000 Subject: r11137: Compile with only 2 warnings (I'm still working on that code) on a gcc4 x86_64 box. Jeremy. (This used to be commit d720867a788c735e56d53d63265255830ec21208) --- source3/libads/kerberos.c | 2 +- source3/libads/krb5_setpw.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index c25f9e4bde..004079529f 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -88,7 +88,7 @@ int kerberos_kinit_password(const char *principal, return code; } - if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, password, + if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, CONST_DISCARD(char *,password), kerb_prompter, NULL, 0, NULL, NULL))) { krb5_free_principal(ctx, me); diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index c261d15c21..5488c5908f 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -341,7 +341,8 @@ static ADS_STATUS do_krb5_kpasswd_request(krb5_context context, { krb5_auth_context auth_context = NULL; krb5_data ap_req, chpw_req, chpw_rep; - int ret, sock, addr_len; + int ret, sock; + socklen_t addr_len; struct sockaddr remote_addr, local_addr; krb5_address local_kaddr, remote_kaddr; -- cgit From ad93243f2399c2f349434dbbb33ed3766a817a8d Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 19 Oct 2005 14:34:17 +0000 Subject: r11183: add small helper function to return a PAC_LOGON_INFO. Guenther (This used to be commit a8d5d6b845efb62e73e281549528376f3ee74211) --- source3/libads/authdata.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c index 9fd30e9dfb..55e736ce6a 100644 --- a/source3/libads/authdata.c +++ b/source3/libads/authdata.c @@ -924,4 +924,20 @@ out: return nt_status; } + PAC_LOGON_INFO *get_logon_info_from_pac(PAC_DATA *pac_data) +{ + PAC_LOGON_INFO *logon_info = NULL; + int i; + + for (i=0; i < pac_data->num_buffers; i++) { + + if (pac_data->pac_buffer[i].type != PAC_TYPE_LOGON_INFO) + continue; + + logon_info = pac_data->pac_buffer[i].ctr->pac.logon_info; + break; + } + return logon_info; +} + #endif -- cgit From c9effb004cb4bb9baa87fb429f22c834226708bb Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 2 Nov 2005 00:19:26 +0000 Subject: r11451: Fix -O1 "might be using uninitialized" errors. Jeremy. (This used to be commit cab76c3c33883aad444eefb6562ab1b27d9ca88a) --- source3/libads/ldap_utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap_utils.c b/source3/libads/ldap_utils.c index 03cdd339f0..18caa2c63a 100644 --- a/source3/libads/ldap_utils.c +++ b/source3/libads/ldap_utils.c @@ -31,7 +31,7 @@ ADS_STATUS ads_do_search_retry(ADS_STRUCT *ads, const char *bind_path, int scope const char *expr, const char **attrs, void **res) { - ADS_STATUS status; + ADS_STATUS status = ADS_SUCCESS; int count = 3; char *bp; -- cgit From 97ecce03de5d4e9e9e3f9bab55af0fe171045085 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 4 Nov 2005 17:39:42 +0000 Subject: r11504: Added Andrew Bartletts removal of another NTLMSSP implementation patch. Jeremy. (This used to be commit 4591984176fd32ba25155fbc6889a1c637019a08) --- source3/libads/ads_struct.c | 2 + source3/libads/sasl.c | 174 ++++++++++++++++++++++---------------------- 2 files changed, 91 insertions(+), 85 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index d8676d050d..55a6d66440 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -105,6 +105,8 @@ ADS_STRUCT *ads_init(const char *realm, /* the caller will own the memory by default */ ads->is_mine = 1; + ads->auth.flags = ADS_AUTH_DISABLE_KERBEROS | ADS_AUTH_ALLOW_NTLMSSP; + return ads; } diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 72cbf7264e..44a95f5990 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -28,108 +28,112 @@ */ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) { - const char *mechs[] = {OID_NTLMSSP, NULL}; DATA_BLOB msg1 = data_blob(NULL, 0); - DATA_BLOB blob, chal1, chal2, auth; - uint8 challenge[8]; - uint8 nthash[24], lmhash[24], sess_key[16]; - uint32 neg_flags; + DATA_BLOB blob = data_blob(NULL, 0); + DATA_BLOB blob_in = data_blob(NULL, 0); + DATA_BLOB blob_out = data_blob(NULL, 0); struct berval cred, *scred = NULL; - ADS_STATUS status; int rc; + NTSTATUS nt_status; + int turn = 1; - if (!ads->auth.password) { - /* No password, don't segfault below... */ - return ADS_ERROR_NT(NT_STATUS_LOGON_FAILURE); - } - - neg_flags = NTLMSSP_NEGOTIATE_UNICODE | - NTLMSSP_NEGOTIATE_128 | - NTLMSSP_NEGOTIATE_NTLM; - - memset(sess_key, 0, 16); - - /* generate the ntlmssp negotiate packet */ - msrpc_gen(&blob, "CddB", - "NTLMSSP", - NTLMSSP_NEGOTIATE, - neg_flags, - sess_key, 16); + struct ntlmssp_state *ntlmssp_state; - /* and wrap it in a SPNEGO wrapper */ - msg1 = gen_negTokenTarg(mechs, blob); - data_blob_free(&blob); - - cred.bv_val = (char *)msg1.data; - cred.bv_len = msg1.length; - - rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred); - if (rc != LDAP_SASL_BIND_IN_PROGRESS) { - status = ADS_ERROR(rc); - goto failed; + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_client_start(&ntlmssp_state))) { + return ADS_ERROR_NT(nt_status); } + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SIGN; - blob = data_blob(scred->bv_val, scred->bv_len); - ber_bvfree(scred); - - /* the server gives us back two challenges */ - if (!spnego_parse_challenge(blob, &chal1, &chal2)) { - DEBUG(3,("Failed to parse challenges\n")); - status = ADS_ERROR(LDAP_OPERATIONS_ERROR); - goto failed; + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, ads->auth.user_name))) { + return ADS_ERROR_NT(nt_status); + } + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, ads->auth.realm))) { + return ADS_ERROR_NT(nt_status); + } + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_password(ntlmssp_state, ads->auth.password))) { + return ADS_ERROR_NT(nt_status); } - data_blob_free(&blob); - - /* encrypt the password with the challenge */ - memcpy(challenge, chal1.data + 24, 8); - SMBencrypt(ads->auth.password, challenge,lmhash); - SMBNTencrypt(ads->auth.password, challenge,nthash); - - data_blob_free(&chal1); - data_blob_free(&chal2); - - /* this generates the actual auth packet */ - msrpc_gen(&blob, "CdBBUUUBd", - "NTLMSSP", - NTLMSSP_AUTH, - lmhash, 24, - nthash, 24, - lp_workgroup(), - ads->auth.user_name, - global_myname(), - sess_key, 16, - neg_flags); - - /* wrap it in SPNEGO */ - auth = spnego_gen_auth(blob); + blob_in = data_blob(NULL, 0); + + do { + nt_status = ntlmssp_update(ntlmssp_state, + blob_in, &blob_out); + data_blob_free(&blob_in); + if ((NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED) + || NT_STATUS_IS_OK(nt_status)) + && blob_out.length) { + if (turn == 1) { + /* and wrap it in a SPNEGO wrapper */ + msg1 = gen_negTokenInit(OID_NTLMSSP, blob_out); + } else { + /* wrap it in SPNEGO */ + msg1 = spnego_gen_auth(blob_out); + } - data_blob_free(&blob); + data_blob_free(&blob_out); - /* Remember to free the msg1 blob. The contents of this - have been copied into cred and need freeing before reassignment. */ - data_blob_free(&msg1); + cred.bv_val = (char *)msg1.data; + cred.bv_len = msg1.length; + scred = NULL; + rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred); + data_blob_free(&msg1); + if ((rc != LDAP_SASL_BIND_IN_PROGRESS) && (rc != 0)) { + if (scred) { + ber_bvfree(scred); + } - /* now send the auth packet and we should be done */ - cred.bv_val = (char *)auth.data; - cred.bv_len = auth.length; + ntlmssp_end(&ntlmssp_state); + return ADS_ERROR(rc); + } + if (scred) { + blob = data_blob(scred->bv_val, scred->bv_len); + ber_bvfree(scred); + } else { + blob = data_blob(NULL, 0); + } - rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred); + } else { - ber_bvfree(scred); - data_blob_free(&auth); + ntlmssp_end(&ntlmssp_state); + data_blob_free(&blob_out); + return ADS_ERROR_NT(nt_status); + } + + if ((turn == 1) && + (rc == LDAP_SASL_BIND_IN_PROGRESS)) { + DATA_BLOB tmp_blob = data_blob(NULL, 0); + /* the server might give us back two challenges */ + if (!spnego_parse_challenge(blob, &blob_in, + &tmp_blob)) { + + ntlmssp_end(&ntlmssp_state); + data_blob_free(&blob); + DEBUG(3,("Failed to parse challenges\n")); + return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); + } + data_blob_free(&tmp_blob); + } else if (rc == LDAP_SASL_BIND_IN_PROGRESS) { + if (!spnego_parse_auth_response(blob, nt_status, + &blob_in)) { + + ntlmssp_end(&ntlmssp_state); + data_blob_free(&blob); + DEBUG(3,("Failed to parse auth response\n")); + return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); + } + } + data_blob_free(&blob); + data_blob_free(&blob_out); + turn++; + } while (rc == LDAP_SASL_BIND_IN_PROGRESS && !NT_STATUS_IS_OK(nt_status)); - return ADS_ERROR(rc); - -failed: + /* we have a reference conter on ntlmssp_state, if we are signing + then the state will be kept by the signing engine */ - /* Remember to free the msg1 blob. The contents of this - have been copied into cred and need freeing. */ - data_blob_free(&msg1); + ntlmssp_end(&ntlmssp_state); - if(scred) - ber_bvfree(scred); - return status; + return ADS_ERROR(rc); } /* -- cgit From 65ed4d3efda243f526131fd145c72647785f9906 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 5 Nov 2005 00:02:01 +0000 Subject: r11508: Removed incorrect patch hunk. Thanks to Andrew Bartlett for pointing this out. Jeremy. (This used to be commit c93a08be4a29854354a16c6e8f984477e19f41c0) --- source3/libads/ads_struct.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index 55a6d66440..d8676d050d 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -105,8 +105,6 @@ ADS_STRUCT *ads_init(const char *realm, /* the caller will own the memory by default */ ads->is_mine = 1; - ads->auth.flags = ADS_AUTH_DISABLE_KERBEROS | ADS_AUTH_ALLOW_NTLMSSP; - return ads; } -- cgit From f99b429446595944991bd2b3e9f4e6a9dd2c13cb Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 7 Nov 2005 14:16:50 +0000 Subject: r11551: Add a few more initialize_krb5_error_table (This used to be commit d92c83aa42fe64a0e996094d1a983f0279c7c707) --- source3/libads/kerberos.c | 2 ++ source3/libads/krb5_setpw.c | 2 ++ 2 files changed, 4 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 004079529f..7f855add06 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -70,6 +70,7 @@ int kerberos_kinit_password(const char *principal, krb5_principal me; krb5_creds my_creds; + initialize_krb5_error_table(); if ((code = krb5_init_context(&ctx))) return code; @@ -155,6 +156,7 @@ int ads_kdestroy(const char *cc_name) krb5_context ctx = NULL; krb5_ccache cc = NULL; + initialize_krb5_error_table(); if ((code = krb5_init_context (&ctx))) { DEBUG(3, ("ads_kdestroy: kdb5_init_context failed: %s\n", error_message(code))); diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 5488c5908f..31d0a02cad 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -472,6 +472,7 @@ ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ, ZERO_STRUCT(creds); + initialize_krb5_error_table(); ret = krb5_init_context(&context); if (ret) { DEBUG(1,("Failed to init krb5 context (%s)\n", error_message(ret))); @@ -604,6 +605,7 @@ static ADS_STATUS ads_krb5_chg_password(const char *kdc_host, krb5_creds creds; char *chpw_princ = NULL, *password; + initialize_krb5_error_table(); ret = krb5_init_context(&context); if (ret) { DEBUG(1,("Failed to init krb5 context (%s)\n", error_message(ret))); -- cgit From 438d0ad451678c42614ab800bceaf490e09c120a Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 10 Nov 2005 19:50:09 +0000 Subject: r11651: After talking to Jeremy, commit my winbindd "Do the Right Thing" patch. Still needs some more testing ni domains with multiple DCs. Coming next.... (This used to be commit aaed605206a8549cec575dab31e56bf6d32f26a6) --- source3/libads/kerberos.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 7f855add06..d5b4b11fa2 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -130,8 +130,25 @@ int ads_kinit_password(ADS_STRUCT *ads) { char *s; int ret; + const char *account_name; + fstring acct_name; - if (asprintf(&s, "%s@%s", ads->auth.user_name, ads->auth.realm) == -1) { + if ( IS_DC ) { + /* this will end up getting a ticket for DOMAIN@RUSTED.REA.LM */ + account_name = lp_workgroup(); + } else { + /* always use the sAMAccountName for security = domain */ + /* global_myname()$@REA.LM */ + if ( lp_security() == SEC_DOMAIN ) { + fstr_sprintf( acct_name, "%s$", global_myname() ); + account_name = acct_name; + } + else + /* This looks like host/global_myname()@REA.LM */ + account_name = ads->auth.user_name; + } + + if (asprintf(&s, "%s@%s", account_name, ads->auth.realm) == -1) { return KRB5_CC_NOMEM; } -- cgit From 90603cb3cddcab3c7577cdad81e4a134c39de4ce Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 22 Nov 2005 10:22:59 +0000 Subject: r11846: Destroy the TALLOC_CTX on error in the Kerberos session setup and give a more precise inline comment why PAC verification may fail. Guenther (This used to be commit 43b57715e9b44a0a0c7cc7fe3674a5fd4369e78b) --- source3/libads/kerberos_verify.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index f21577d080..220bf14e32 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -400,9 +400,9 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, file_save("/tmp/ticket.dat", ticket->data, ticket->length); #endif - /* continue when no PAC is retrieved - (like accounts that have the UF_NO_AUTH_DATA_REQUIRED flag set, - or Kerberos tickets encryped using a DES key) - Guenther */ + /* continue when no PAC is retrieved or we couldn't decode the PAC + (like accounts that have the UF_NO_AUTH_DATA_REQUIRED flag set, or + Kerberos tickets encrypted using a DES key) - Guenther */ got_auth_data = get_auth_data_from_tkt(mem_ctx, &auth_data, tkt); if (!got_auth_data) { -- cgit From ac331c48db29afeb712bb1a1edf739354082ad7f Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 22 Nov 2005 17:15:28 +0000 Subject: r11863: BUG 3196: patch from Alex Deiter to compile against the Sun LDAP client libs. But not for AD support; just ldap support (This used to be commit a33e78acedb37df47905d326411e017794721250) --- source3/libads/ldap.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index bf402b3499..6d1ca24537 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -577,8 +577,10 @@ ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, status = ads_do_paged_search(ads, bind_path, scope, expr, attrs, res, &count, &cookie); - if (!ADS_ERR_OK(status)) return status; + if (!ADS_ERR_OK(status)) + return status; +#ifdef HAVE_LDAP_ADD_RESULT_ENTRY while (cookie) { void *res2 = NULL; ADS_STATUS status2; @@ -598,6 +600,10 @@ ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, /* note that we do not free res2, as the memory is now part of the main returned list */ } +#else + DEBUG(0, ("no ldap_add_result_entry() support in LDAP libs!\n")); + status = ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL); +#endif return status; } -- cgit From f6b8327fac33a7758f1c66131238a1945807e535 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 23 Nov 2005 11:21:16 +0000 Subject: r11875: Allow to use START_TLS (by manually setting "ldap ssl = start_tls") for LDAP connections to ADS (Windows 2003). Guenther (This used to be commit 95543fab0f6aa1c483b40247c16cde79cbc9c012) --- source3/libads/ldap.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 6d1ca24537..e4cfc456a2 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -292,6 +292,11 @@ got_connection: ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); + status = ADS_ERROR(smb_ldap_start_tls(ads->ld, version)); + if (!ADS_ERR_OK(status)) { + return status; + } + if (!ads->auth.user_name) { /* have to use the userPrincipalName value here and not servicePrincipalName; found by Guenther Deschner @ Sernet */ -- cgit From d1f91f7c723733113b4e9792042101c80dfc064c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 3 Dec 2005 06:46:46 +0000 Subject: r12043: It's amazing the warnings you find when compiling on a 64-bit box with gcc4 and -O6... Fix a bunch of C99 dereferencing type-punned pointer will break strict-aliasing rules errors. Also added prs_int32 (not uint32...) as it's needed in one place. Find places where prs_uint32 was being used to marshall/unmarshall a time_t (a big no no on 64-bits). More warning fixes to come. Thanks to Volker for nudging me to compile like this. Jeremy. (This used to be commit c65b752604f8f58abc4e7ae8514dc2c7f086271c) --- source3/libads/ads_ldap.c | 2 +- source3/libads/ldap.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_ldap.c b/source3/libads/ads_ldap.c index ae86ef0b76..fea4cd0fd0 100644 --- a/source3/libads/ads_ldap.c +++ b/source3/libads/ads_ldap.c @@ -56,7 +56,7 @@ ADS_STATUS ads_sid_to_dn(ADS_STRUCT *ads, goto done; } - rc = ads_search_retry(ads, (void **)&msg, ldap_exp, attr); + rc = ads_search_retry(ads, (void **)(void *)&msg, ldap_exp, attr); if (!ADS_ERR_OK(rc)) { DEBUG(1,("ads_sid_to_dn ads_search: %s\n", ads_errstr(rc))); diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index e4cfc456a2..fa2a8b5ea5 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1162,7 +1162,7 @@ uint32 ads_get_kvno(ADS_STRUCT *ads, const char *machine_name) if (asprintf(&filter, "(samAccountName=%s$)", machine_name) == -1) { return kvno; } - ret = ads_search(ads, (void**) &res, filter, attrs); + ret = ads_search(ads, (void**)(void *)&res, filter, attrs); SAFE_FREE(filter); if (!ADS_ERR_OK(ret) && ads_count_replies(ads, res)) { DEBUG(1,("ads_get_kvno: Computer Account For %s not found.\n", machine_name)); @@ -1216,7 +1216,7 @@ ADS_STATUS ads_clear_service_principal_names(ADS_STRUCT *ads, const char *machin ADS_STATUS ret = ADS_ERROR(LDAP_SUCCESS); char *dn_string = NULL; - ret = ads_find_machine_acct(ads, (void **)&res, machine_name); + ret = ads_find_machine_acct(ads, (void **)(void *)&res, machine_name); if (!ADS_ERR_OK(ret) || ads_count_replies(ads, res) != 1) { DEBUG(5,("ads_clear_service_principal_names: WARNING: Host Account for %s not found... skipping operation.\n", machine_name)); DEBUG(5,("ads_clear_service_principal_names: WARNING: Service Principals for %s have NOT been cleared.\n", machine_name)); @@ -1284,7 +1284,7 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n char *dn_string = NULL; const char *servicePrincipalName[4] = {NULL, NULL, NULL, NULL}; - ret = ads_find_machine_acct(ads, (void **)&res, machine_name); + ret = ads_find_machine_acct(ads, (void **)(void *)&res, machine_name); if (!ADS_ERR_OK(ret) || ads_count_replies(ads, res) != 1) { DEBUG(1,("ads_add_service_principal_name: WARNING: Host Account for %s not found... skipping operation.\n", machine_name)); @@ -1398,7 +1398,7 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *machine_name name_to_fqdn(my_fqdn, machine_name); - status = ads_find_machine_acct(ads, (void **)&res, machine_name); + status = ads_find_machine_acct(ads, (void **)(void *)&res, machine_name); if (ADS_ERR_OK(status) && ads_count_replies(ads, res) == 1) { char *dn_string = ads_get_dn(ads, res); if (!dn_string) { @@ -1771,7 +1771,7 @@ ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *machine_name, return status; } - status = ads_find_machine_acct(ads, (void **)&res, machine); + status = ads_find_machine_acct(ads, (void **)(void *)&res, machine); if (!ADS_ERR_OK(status)) { DEBUG(0, ("ads_join_realm: Host account test failed for machine %s\n", machine)); SAFE_FREE(machine); -- cgit From 3f6d9a7b9d35331992fdd069b7752f3082fe0b1b Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 12 Dec 2005 18:55:54 +0000 Subject: r12196: patch from Krishna Ganugapati Use the subtree delete ldap control when running 'net ads leave' to ensure that the machine account is actually deleted. (This used to be commit e96000c16cd182b2e2cbdc1a287002306d2965e6) --- source3/libads/ldap.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index fa2a8b5ea5..8c8401dff9 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -37,6 +37,9 @@ * codepoints in UTF-8). This may have to change at some point **/ + +#define LDAP_SERVER_TREE_DELETE_OID "1.2.840.113556.1.4.805" + static SIG_ATOMIC_T gotalarm; /*************************************************************** @@ -1796,6 +1799,11 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) void *res, *msg; char *hostnameDN, *host; int rc; + LDAPControl ldap_control; + LDAPControl * pldap_control[] = {&ldap_control, 0}; + + memset(&ldap_control, 0, sizeof(LDAPControl)); + ldap_control.ldctl_oid = (char *)LDAP_SERVER_TREE_DELETE_OID; /* hostname must be lowercase */ host = SMB_STRDUP(hostname); @@ -1813,7 +1821,15 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) } hostnameDN = ads_get_dn(ads, (LDAPMessage *)msg); - rc = ldap_delete_s(ads->ld, hostnameDN); + + + rc = ldap_delete_ext_s(ads->ld, hostnameDN, pldap_control, NULL); + if (rc) { + DEBUG(3,("ldap_delete_ext_s failed with error code %d\n", rc)); + }else { + DEBUG(3,("ldap_delete_ext_s succeeded with error code %d\n", rc)); + } + ads_memfree(ads, hostnameDN); if (rc != LDAP_SUCCESS) { return ADS_ERROR(rc); -- cgit From 568e8003bc48ec18118358b98c2d1131efd6ff45 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 21 Dec 2005 10:05:39 +0000 Subject: r12406: Since w2k3 sp1 we fail to create user accounts using e.g. "net ads user add" with "Server is unwilling to perform". Seems we have to put in the same userAccountControl bits the server would pick when we wouldn't send them at all. Guenther (This used to be commit fd5da5875cdc47fc6ef6ba1615a9635f9f157589) --- source3/libads/ldap_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap_user.c b/source3/libads/ldap_user.c index 56a0d8013b..3ff6acc9e8 100644 --- a/source3/libads/ldap_user.c +++ b/source3/libads/ldap_user.c @@ -65,7 +65,7 @@ ADS_STATUS ads_add_user_acct(ADS_STRUCT *ads, const char *user, if (!(new_dn = talloc_asprintf(ctx, "cn=%s,%s,%s", name, container, ads->config.bind_path))) goto done; - if (!(controlstr = talloc_asprintf(ctx, "%u", UF_NORMAL_ACCOUNT))) + if (!(controlstr = talloc_asprintf(ctx, "%u", (UF_NORMAL_ACCOUNT | UF_ACCOUNTDISABLE)))) goto done; if (!(mods = ads_init_mods(ctx))) goto done; -- cgit From 92092cbcdcdb01448ef4e6acd9af88dd93c6c288 Mon Sep 17 00:00:00 2001 From: James Peach Date: Fri, 13 Jan 2006 00:07:54 +0000 Subject: r12878: Don't use non-static array initialisers. (This used to be commit 95b231f0285c65bcdc62cd453cea634f9f5e7f91) --- source3/libads/ldap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 8c8401dff9..dc93bd556c 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1800,8 +1800,9 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) char *hostnameDN, *host; int rc; LDAPControl ldap_control; - LDAPControl * pldap_control[] = {&ldap_control, 0}; + LDAPControl * pldap_control[2] = {NULL, NULL}; + pldap_control[0] = &ldap_control; memset(&ldap_control, 0, sizeof(LDAPControl)); ldap_control.ldctl_oid = (char *)LDAP_SERVER_TREE_DELETE_OID; -- cgit From 14b16baf69aff50dbeb537a7d09236ca66a6568d Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 25 Jan 2006 21:25:25 +0000 Subject: r13137: make cleare where long ifdefs ends (This used to be commit 58e48fef450f71ac15219f73897801c5a66a2c44) --- source3/libads/sasl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 44a95f5990..f6adfb5108 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -419,7 +419,7 @@ failed: ber_bvfree(scred); return status; } -#endif +#endif /* HAVE_GGSAPI */ /* mapping between SASL mechanisms and functions */ static struct { @@ -466,5 +466,5 @@ ADS_STATUS ads_sasl_bind(ADS_STRUCT *ads) return ADS_ERROR(LDAP_AUTH_METHOD_NOT_SUPPORTED); } -#endif +#endif /* HAVE_LDAP */ -- cgit From 855e02f1649992f05b685be96dfff4a9140170e9 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 3 Feb 2006 21:19:24 +0000 Subject: r13310: first round of server affinity patches for winbindd & net ads join (This used to be commit 6c3480f9aecc061660ad5c06347b8f1d3e11a330) --- source3/libads/ldap.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index dc93bd556c..e503da62a4 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -136,6 +136,10 @@ BOOL ads_try_connect(ADS_STRUCT *ads, const char *server, unsigned port) ads->ldap_port = port; ads->ldap_ip = *interpret_addr2(srv); free(srv); + + /* cache the successful connection */ + + saf_store( ads->server.workgroup, server ); return True; } -- cgit From 0af1500fc0bafe61019f1b2ab1d9e1d369221240 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 3 Feb 2006 22:19:41 +0000 Subject: r13316: Let the carnage begin.... Sync with trunk as off r13315 (This used to be commit 17e63ac4ed8325c0d44fe62b2442449f3298559f) --- source3/libads/gpo.c | 680 ++++++++++++++++++++++++++++++++++++++++++++ source3/libads/gpo_util.c | 496 ++++++++++++++++++++++++++++++++ source3/libads/kerberos.c | 40 ++- source3/libads/krb5_errs.c | 132 +++++++++ source3/libads/krb5_setpw.c | 49 ++-- source3/libads/ldap.c | 223 +++++++++++++++ source3/libads/sasl.c | 23 +- 7 files changed, 1611 insertions(+), 32 deletions(-) create mode 100644 source3/libads/gpo.c create mode 100644 source3/libads/gpo_util.c create mode 100644 source3/libads/krb5_errs.c (limited to 'source3/libads') diff --git a/source3/libads/gpo.c b/source3/libads/gpo.c new file mode 100644 index 0000000000..9cf7aae977 --- /dev/null +++ b/source3/libads/gpo.c @@ -0,0 +1,680 @@ +/* + * Unix SMB/CIFS implementation. + * Group Policy Object Support + * Copyright (C) Guenther Deschner 2005 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "includes.h" + +ADS_STATUS ads_parse_gp_ext(TALLOC_CTX *mem_ctx, + const char *extension_raw, + struct GP_EXT *gp_ext) +{ + char **ext_list; + char **ext_strings; + int i; + + DEBUG(20,("ads_parse_gp_ext: %s\n", extension_raw)); + + ext_list = str_list_make_talloc(mem_ctx, extension_raw, "]"); + if (ext_list == NULL) { + goto parse_error; + } + + for (i = 0; ext_list[i] != NULL; i++) { + /* no op */ + } + + gp_ext->num_exts = i; + + gp_ext->extensions = TALLOC_ZERO_ARRAY(mem_ctx, char *, gp_ext->num_exts); + gp_ext->extensions_guid = TALLOC_ZERO_ARRAY(mem_ctx, char *, gp_ext->num_exts); + gp_ext->snapins = TALLOC_ZERO_ARRAY(mem_ctx, char *, gp_ext->num_exts); + gp_ext->snapins_guid = TALLOC_ZERO_ARRAY(mem_ctx, char *, gp_ext->num_exts); + + gp_ext->gp_extension = talloc_strdup(mem_ctx, extension_raw); + + if (gp_ext->extensions == NULL || gp_ext->extensions_guid == NULL || + gp_ext->snapins == NULL || gp_ext->snapins_guid == NULL || + gp_ext->gp_extension == NULL) { + goto parse_error; + } + + for (i = 0; ext_list[i] != NULL; i++) { + + int k; + char *p, *q; + + DEBUGADD(10,("extension #%d\n", i)); + + p = ext_list[i]; + + if (p[0] == '[') { + p++; + } + + ext_strings = str_list_make_talloc(mem_ctx, p, "}"); + if (ext_strings == NULL) { + goto parse_error; + } + + for (k = 0; ext_strings[k] != NULL; k++) { + /* no op */ + } + + q = ext_strings[0]; + + if (q[0] == '{') { + q++; + } + + gp_ext->extensions[i] = talloc_strdup(mem_ctx, cse_gpo_guid_string_to_name(q)); + gp_ext->extensions_guid[i] = talloc_strdup(mem_ctx, q); + + /* we might have no name for the guid */ + if (gp_ext->extensions_guid[i] == NULL) { + goto parse_error; + } + + for (k = 1; ext_strings[k] != NULL; k++) { + + char *m = ext_strings[k]; + + if (m[0] == '{') { + m++; + } + + /* FIXME: theoretically there could be more than one snapin per extension */ + gp_ext->snapins[i] = talloc_strdup(mem_ctx, cse_snapin_gpo_guid_string_to_name(m)); + gp_ext->snapins_guid[i] = talloc_strdup(mem_ctx, m); + + /* we might have no name for the guid */ + if (gp_ext->snapins_guid[i] == NULL) { + goto parse_error; + } + } + } + + if (ext_list) { + str_list_free_talloc(mem_ctx, &ext_list); + } + if (ext_strings) { + str_list_free_talloc(mem_ctx, &ext_strings); + } + + return ADS_ERROR(LDAP_SUCCESS); + +parse_error: + if (ext_list) { + str_list_free_talloc(mem_ctx, &ext_list); + } + if (ext_strings) { + str_list_free_talloc(mem_ctx, &ext_strings); + } + + return ADS_ERROR(LDAP_NO_MEMORY); +} + +ADS_STATUS ads_parse_gplink(TALLOC_CTX *mem_ctx, + const char *gp_link_raw, + uint32 options, + struct GP_LINK *gp_link) +{ + char **link_list; + int i; + + DEBUG(10,("ads_parse_gplink: gPLink: %s\n", gp_link_raw)); + + link_list = str_list_make_talloc(mem_ctx, gp_link_raw, "]"); + if (link_list == NULL) { + goto parse_error; + } + + for (i = 0; link_list[i] != NULL; i++) { + /* no op */ + } + + gp_link->gp_opts = options; + gp_link->num_links = i; + + gp_link->link_names = TALLOC_ZERO_ARRAY(mem_ctx, char *, gp_link->num_links); + gp_link->link_opts = TALLOC_ZERO_ARRAY(mem_ctx, uint32, gp_link->num_links); + + gp_link->gp_link = talloc_strdup(mem_ctx, gp_link_raw); + + if (gp_link->link_names == NULL || gp_link->link_opts == NULL || gp_link->gp_link == NULL) { + goto parse_error; + } + + for (i = 0; link_list[i] != NULL; i++) { + + char *p, *q; + + DEBUGADD(10,("ads_parse_gplink: processing link #%d\n", i)); + + q = link_list[i]; + if (q[0] == '[') { + q++; + }; + + p = strchr(q, ';'); + + if (p == NULL) { + goto parse_error; + } + + gp_link->link_names[i] = talloc_strdup(mem_ctx, q); + if (gp_link->link_names[i] == NULL) { + goto parse_error; + } + gp_link->link_names[i][PTR_DIFF(p, q)] = 0; + + gp_link->link_opts[i] = atoi(p + 1); + + DEBUGADD(10,("ads_parse_gplink: link: %s\n", gp_link->link_names[i])); + DEBUGADD(10,("ads_parse_gplink: opt: %d\n", gp_link->link_opts[i])); + + } + + if (link_list) { + str_list_free_talloc(mem_ctx, &link_list); + } + + return ADS_ERROR(LDAP_SUCCESS); + +parse_error: + if (link_list) { + str_list_free_talloc(mem_ctx, &link_list); + } + + return ADS_ERROR(LDAP_NO_MEMORY); +} + +ADS_STATUS ads_get_gpo_link(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + const char *link_dn, + struct GP_LINK *gp_link_struct) +{ + ADS_STATUS status; + const char *attrs[] = {"gPLink", "gPOptions", NULL}; + void *res = NULL; + const char *gp_link; + uint32 gp_options; + + ZERO_STRUCTP(gp_link_struct); + + status = ads_search_dn(ads, &res, link_dn, attrs); + if (!ADS_ERR_OK(status)) { + DEBUG(10,("ads_get_gpo_link: search failed with %s\n", ads_errstr(status))); + return status; + } + + if (ads_count_replies(ads, res) != 1) { + DEBUG(10,("ads_get_gpo_link: no result\n")); + ads_msgfree(ads, res); + return ADS_ERROR(LDAP_NO_SUCH_OBJECT); + } + + gp_link = ads_pull_string(ads, mem_ctx, res, "gPLink"); + if (gp_link == NULL) { + DEBUG(10,("ads_get_gpo_link: no 'gPLink' attribute found\n")); + ads_msgfree(ads, res); + return ADS_ERROR(LDAP_NO_SUCH_ATTRIBUTE); + } + + if (!ads_pull_uint32(ads, res, "gPOptions", &gp_options)) { + DEBUG(10,("ads_get_gpo_link: no 'gPOptions' attribute found\n")); + gp_options = 0; + } + + ads_msgfree(ads, res); + + return ads_parse_gplink(mem_ctx, gp_link, gp_options, gp_link_struct); +} + +ADS_STATUS ads_add_gpo_link(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + const char *link_dn, + const char *gpo_dn, + uint32 gpo_opt) +{ + ADS_STATUS status; + const char *attrs[] = {"gPLink", NULL}; + void *res = NULL; + const char *gp_link, *gp_link_new; + ADS_MODLIST mods; + + + /* although ADS allows to set anything here, we better check here if + * the gpo_dn is sane */ + + if (!strnequal(gpo_dn, "LDAP://CN={", strlen("LDAP://CN={")) != 0) { + return ADS_ERROR(LDAP_INVALID_DN_SYNTAX); + } + + status = ads_search_dn(ads, &res, link_dn, attrs); + if (!ADS_ERR_OK(status)) { + DEBUG(10,("ads_add_gpo_link: search failed with %s\n", ads_errstr(status))); + return status; + } + + if (ads_count_replies(ads, res) != 1) { + DEBUG(10,("ads_add_gpo_link: no result\n")); + return ADS_ERROR(LDAP_NO_SUCH_OBJECT); + } + + gp_link = ads_pull_string(ads, mem_ctx, res, "gPLink"); + if (gp_link == NULL) { + gp_link_new = talloc_asprintf(mem_ctx, "[%s;%d]", gpo_dn, gpo_opt); + } else { + gp_link_new = talloc_asprintf(mem_ctx, "%s[%s;%d]", gp_link, gpo_dn, gpo_opt); + } + + if (gp_link_new == NULL) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + + mods = ads_init_mods(mem_ctx); + if (mods == NULL) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + + status = ads_mod_str(mem_ctx, &mods, "gPLink", gp_link_new); + if (!ADS_ERR_OK(status)) { + return status; + } + + return ads_gen_mod(ads, link_dn, mods); +} + +/* untested & broken */ +ADS_STATUS ads_delete_gpo_link(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + const char *link_dn, + const char *gpo_dn) +{ + ADS_STATUS status; + const char *attrs[] = {"gPLink", NULL}; + void *res = NULL; + const char *gp_link, *gp_link_new = NULL; + ADS_MODLIST mods; + + /* check for a sane gpo_dn */ + if (gpo_dn[0] != '[') { + DEBUG(10,("ads_delete_gpo_link: first char not: [\n")); + return ADS_ERROR(LDAP_INVALID_DN_SYNTAX); + } + + if (gpo_dn[strlen(gpo_dn)] != ']') { + DEBUG(10,("ads_delete_gpo_link: last char not: ]\n")); + return ADS_ERROR(LDAP_INVALID_DN_SYNTAX); + } + + status = ads_search_dn(ads, &res, link_dn, attrs); + if (!ADS_ERR_OK(status)) { + DEBUG(10,("ads_delete_gpo_link: search failed with %s\n", ads_errstr(status))); + return status; + } + + if (ads_count_replies(ads, res) != 1) { + DEBUG(10,("ads_delete_gpo_link: no result\n")); + return ADS_ERROR(LDAP_NO_SUCH_OBJECT); + } + + gp_link = ads_pull_string(ads, mem_ctx, res, "gPLink"); + if (gp_link == NULL) { + return ADS_ERROR(LDAP_NO_SUCH_ATTRIBUTE); + } + + /* find link to delete */ +// gp_link_new = talloc_asprintf(mem_ctx, "%s[%s;%d]", gp_link, gpo_dn, gpo_opt); + + if (gp_link_new == NULL) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + + mods = ads_init_mods(mem_ctx); + if (mods == NULL) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + + status = ads_mod_str(mem_ctx, &mods, "gPLink", gp_link_new); + if (!ADS_ERR_OK(status)) { + return status; + } + + return ads_gen_mod(ads, link_dn, mods); +} + +ADS_STATUS ads_parse_gpo(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + void *res, + const char *gpo_dn, + struct GROUP_POLICY_OBJECT *gpo) +{ + ZERO_STRUCTP(gpo); + + if (res == NULL) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + + if (gpo_dn) { + gpo->ds_path = talloc_strdup(mem_ctx, gpo_dn); + } else { + gpo->ds_path = ads_get_dn(ads, res); + } + if (gpo->ds_path == NULL) { + ads_msgfree(ads, res); + return ADS_ERROR(LDAP_NO_MEMORY); + } + + if (!ads_pull_uint32(ads, res, "versionNumber", &gpo->version)) { + ads_msgfree(ads, res); + return ADS_ERROR(LDAP_NO_MEMORY); + } + + /* split here for convenience */ + gpo->version_user = gpo->version >> 16; + gpo->version_machine = gpo->version & 0xffff; + + /* sure ??? */ + if (!ads_pull_uint32(ads, res, "flags", &gpo->options)) { + ads_msgfree(ads, res); + return ADS_ERROR(LDAP_NO_MEMORY); + } + + gpo->file_sys_path = ads_pull_string(ads, mem_ctx, res, "gPCFileSysPath"); + if (gpo->file_sys_path == NULL) { + ads_msgfree(ads, res); + return ADS_ERROR(LDAP_NO_MEMORY); + } + + gpo->display_name = ads_pull_string(ads, mem_ctx, res, "displayName"); + if (gpo->display_name == NULL) { + ads_msgfree(ads, res); + return ADS_ERROR(LDAP_NO_MEMORY); + } + + gpo->name = ads_pull_string(ads, mem_ctx, res, "name"); + if (gpo->name == NULL) { + ads_msgfree(ads, res); + return ADS_ERROR(LDAP_NO_MEMORY); + } + + /* ???, this is optional to have and what does it depend on, the 'flags' ?) */ + gpo->machine_extensions = ads_pull_string(ads, mem_ctx, res, "gPCMachineExtensionNames"); + gpo->user_extensions = ads_pull_string(ads, mem_ctx, res, "gPCUserExtensionNames"); + + ads_msgfree(ads, res); + + return ADS_ERROR(LDAP_SUCCESS); +} + +ADS_STATUS ads_get_gpo(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + const char *gpo_dn, + const char *display_name, + const char *guid_name, + struct GROUP_POLICY_OBJECT *gpo) +{ + ADS_STATUS status; + void *res = NULL; + char *dn; + const char *filter; + const char *attrs[] = { "cn", "displayName", "flags", "gPCFileSysPath", + "gPCFunctionalityVersion", "gPCMachineExtensionNames", + "gPCUserExtensionNames", "gPCWQLFilter", "name", + "versionNumber", NULL}; + + ZERO_STRUCTP(gpo); + + if (!gpo_dn && !display_name && !guid_name) { + return ADS_ERROR(LDAP_NO_SUCH_OBJECT); + } + + if (gpo_dn) { + + if (strnequal(gpo_dn, "LDAP://", strlen("LDAP://")) != 0) { + gpo_dn = gpo_dn + strlen("LDAP://"); + } + + status = ads_search_dn(ads, &res, gpo_dn, attrs); + + } else if (display_name || guid_name) { + + filter = talloc_asprintf(mem_ctx, + "(&(objectclass=groupPolicyContainer)(%s=%s))", + display_name ? "displayName" : "name", + display_name ? display_name : guid_name); + if (filter == NULL) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + + status = ads_do_search_all(ads, ads->config.bind_path, + LDAP_SCOPE_SUBTREE, filter, + attrs, &res); + } + + if (!ADS_ERR_OK(status)) { + DEBUG(10,("ads_get_gpo: search failed with %s\n", ads_errstr(status))); + return status; + } + + if (ads_count_replies(ads, res) != 1) { + DEBUG(10,("ads_get_gpo: no result\n")); + return ADS_ERROR(LDAP_NO_SUCH_OBJECT); + } + + dn = ads_get_dn(ads, res); + if (dn == NULL) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + + status = ads_parse_gpo(ads, mem_ctx, res, dn, gpo); + + ads_memfree(ads, dn); + + return status; +} + +ADS_STATUS add_gplink_to_gpo_list(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + struct GROUP_POLICY_OBJECT **gpo_list, + const char *link_dn, + struct GP_LINK *gp_link, + enum GPO_LINK_TYPE link_type, + BOOL only_add_forced_gpos) +{ + ADS_STATUS status; + int i; + + for (i = 0; i < gp_link->num_links; i++) { + + struct GROUP_POLICY_OBJECT *new_gpo = NULL; + + if (gp_link->link_opts[i] & GPO_LINK_OPT_DISABLED) { + DEBUG(10,("skipping disabled GPO\n")); + continue; + } + + if (only_add_forced_gpos) { + + if (! (gp_link->link_opts[i] & GPO_LINK_OPT_ENFORCED)) { + DEBUG(10,("skipping nonenforced GPO link because GPOPTIONS_BLOCK_INHERITANCE has been set\n")); + continue; + } else { + DEBUG(10,("adding enforced GPO link although the GPOPTIONS_BLOCK_INHERITANCE has been set\n")); + } + } + + new_gpo = TALLOC_P(mem_ctx, struct GROUP_POLICY_OBJECT); + if (new_gpo == NULL) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + + ZERO_STRUCTP(new_gpo); + + status = ads_get_gpo(ads, mem_ctx, gp_link->link_names[i], NULL, NULL, new_gpo); + if (!ADS_ERR_OK(status)) { + return status; + } + + new_gpo->link = link_dn; + new_gpo->link_type = link_type; + + DLIST_ADD(*gpo_list, new_gpo); + + DEBUG(10,("add_gplink_to_gplist: added GPLINK #%d %s to GPO list\n", + i, gp_link->link_names[i])); + } + + return ADS_ERROR(LDAP_SUCCESS); +} + +ADS_STATUS ads_get_gpo_list(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + const char *dn, + uint32 flags, + struct GROUP_POLICY_OBJECT **gpo_list) +{ + /* (L)ocal (S)ite (D)omain (O)rganizational(U)nit */ + + ADS_STATUS status; + struct GP_LINK gp_link; + const char *parent_dn, *site_dn, *tmp_dn; + BOOL add_only_forced_gpos = False; + + ZERO_STRUCTP(gpo_list); + + DEBUG(10,("ads_get_gpo_list: getting GPO list for [%s]\n", dn)); + + /* (L)ocal */ + /* not yet... */ + + /* (S)ite */ + + /* are site GPOs valid for users as well ??? */ + if (flags & GPO_LIST_FLAG_MACHINE) { + + status = ads_site_dn_for_machine(ads, mem_ctx, ads->config.ldap_server_name, &site_dn); + if (!ADS_ERR_OK(status)) { + return status; + } + + DEBUG(10,("ads_get_gpo_list: query SITE: [%s] for GPOs\n", site_dn)); + + status = ads_get_gpo_link(ads, mem_ctx, site_dn, &gp_link); + if (ADS_ERR_OK(status)) { + + if (DEBUGLEVEL >= 100) { + dump_gplink(ads, mem_ctx, &gp_link); + } + + status = add_gplink_to_gpo_list(ads, mem_ctx, gpo_list, + site_dn, &gp_link, GP_LINK_SITE, + add_only_forced_gpos); + if (!ADS_ERR_OK(status)) { + return status; + } + + if (flags & GPO_LIST_FLAG_SITEONLY) { + return ADS_ERROR(LDAP_SUCCESS); + } + + /* inheritance can't be blocked at the site level */ + } + } + + tmp_dn = dn; + + while ( (parent_dn = ads_parent_dn(tmp_dn)) && + (!strequal(parent_dn, ads_parent_dn(ads->config.bind_path))) ) { + + /* (D)omain */ + + /* An account can just be a member of one domain */ + if (strncmp(parent_dn, "DC=", strlen("DC=")) == 0) { + + DEBUG(10,("ads_get_gpo_list: query DC: [%s] for GPOs\n", parent_dn)); + + status = ads_get_gpo_link(ads, mem_ctx, parent_dn, &gp_link); + if (ADS_ERR_OK(status)) { + + if (DEBUGLEVEL >= 100) { + dump_gplink(ads, mem_ctx, &gp_link); + } + + /* block inheritance from now on */ + if (gp_link.gp_opts & GPOPTIONS_BLOCK_INHERITANCE) { + add_only_forced_gpos = True; + } + + status = add_gplink_to_gpo_list(ads, mem_ctx, + gpo_list, parent_dn, + &gp_link, GP_LINK_DOMAIN, + add_only_forced_gpos); + if (!ADS_ERR_OK(status)) { + return status; + } + } + } + + tmp_dn = parent_dn; + } + + /* reset dn again */ + tmp_dn = dn; + + while ( (parent_dn = ads_parent_dn(tmp_dn)) && + (!strequal(parent_dn, ads_parent_dn(ads->config.bind_path))) ) { + + + /* (O)rganizational(U)nit */ + + /* An account can be a member of more OUs */ + if (strncmp(parent_dn, "OU=", strlen("OU=")) == 0) { + + DEBUG(10,("ads_get_gpo_list: query OU: [%s] for GPOs\n", parent_dn)); + + status = ads_get_gpo_link(ads, mem_ctx, parent_dn, &gp_link); + if (ADS_ERR_OK(status)) { + + if (DEBUGLEVEL >= 100) { + dump_gplink(ads, mem_ctx, &gp_link); + } + + /* block inheritance from now on */ + if (gp_link.gp_opts & GPOPTIONS_BLOCK_INHERITANCE) { + add_only_forced_gpos = True; + } + + status = add_gplink_to_gpo_list(ads, mem_ctx, + gpo_list, parent_dn, + &gp_link, GP_LINK_OU, + add_only_forced_gpos); + if (!ADS_ERR_OK(status)) { + return status; + } + } + } + + tmp_dn = parent_dn; + + }; + + return ADS_ERROR(LDAP_SUCCESS); +} diff --git a/source3/libads/gpo_util.c b/source3/libads/gpo_util.c new file mode 100644 index 0000000000..8f913c1971 --- /dev/null +++ b/source3/libads/gpo_util.c @@ -0,0 +1,496 @@ +/* + * Unix SMB/CIFS implementation. + * Group Policy Object Support + * Copyright (C) Guenther Deschner 2005 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "includes.h" + +#define DEFAULT_DOMAIN_POLICY "Default Domain Policy" +#define DEFAULT_DOMAIN_CONTROLLERS_POLICY "Default Domain Controllers Policy" + +/* should we store a parsed guid ? UUID_FLAT guid; */ +struct gpo_table { + const char *name; + const char *guid_string; +}; + +struct snapin_table { + const char *name; + const char *guid_string; + ADS_STATUS (*snapin_fn)(ADS_STRUCT *, TALLOC_CTX *mem_ctx, const char *, const char *); +}; + +static struct gpo_table gpo_default_policy[] = { + { DEFAULT_DOMAIN_POLICY, + "31B2F340-016D-11D2-945F-00C04FB984F9" }, + { DEFAULT_DOMAIN_CONTROLLERS_POLICY, + "6AC1786C-016F-11D2-945F-00C04fB984F9" }, + { NULL, NULL } +}; + + +/* the following is seen in gPCMachineExtensionNames or gPCUserExtensionNames */ + +static struct gpo_table gpo_cse_extensions[] = { + { "Administrative Templates Extension", + "35378EAC-683F-11D2-A89A-00C04FBBCFA2" }, /* Registry Policy ? */ + { "Microsoft Disc Quota", + "3610EDA5-77EF-11D2-8DC5-00C04FA31A66" }, + { "EFS recovery", + "B1BE8D72-6EAC-11D2-A4EA-00C04F79F83A" }, + { "Folder Redirection", + "25537BA6-77A8-11D2-9B6C-0000F8080861" }, + { "IP Security", + "E437BC1C-AA7D-11D2-A382-00C04F991E27" }, + { "Internet Explorer Branding", + "A2E30F80-D7DE-11d2-BBDE-00C04F86AE3B" }, + { "QoS Packet Scheduler", + "426031c0-0b47-4852-b0ca-ac3d37bfcb39" }, + { "Scripts", + "42B5FAAE-6536-11D2-AE5A-0000F87571E3" }, + { "Security", + "827D319E-6EAC-11D2-A4EA-00C04F79F83A" }, + { "Software Installation", + "C6DC5466-785A-11D2-84D0-00C04FB169F7" }, + { "Wireless Group Policy", + "0ACDD40C-75AC-BAA0-BF6DE7E7FE63" }, + { NULL, NULL } +}; + +/* guess work */ +static struct snapin_table gpo_cse_snapin_extensions[] = { + { "Administrative Templates", + "0F6B957D-509E-11D1-A7CC-0000F87571E3", gpo_snapin_handler_none }, + { "Certificates", + "53D6AB1D-2488-11D1-A28C-00C04FB94F17", gpo_snapin_handler_none }, + { "EFS recovery policy processing", + "B1BE8D72-6EAC-11D2-A4EA-00C04F79F83A", gpo_snapin_handler_none }, + { "Folder Redirection policy processing", + "25537BA6-77A8-11D2-9B6C-0000F8080861", gpo_snapin_handler_none }, + { "Folder Redirection", + "88E729D6-BDC1-11D1-BD2A-00C04FB9603F", gpo_snapin_handler_none }, + { "Registry policy processing", + "35378EAC-683F-11D2-A89A-00C04FBBCFA2", gpo_snapin_handler_none }, + { "Remote Installation Services", + "3060E8CE-7020-11D2-842D-00C04FA372D4", gpo_snapin_handler_none }, + { "Security Settings", + "803E14A0-B4FB-11D0-A0D0-00A0C90F574B", gpo_snapin_handler_security_settings }, + { "Security policy processing", + "827D319E-6EAC-11D2-A4EA-00C04F79F83A", gpo_snapin_handler_security_settings }, + { "unknown", + "3060E8D0-7020-11D2-842D-00C04FA372D4", gpo_snapin_handler_none }, + { "unknown2", + "53D6AB1B-2488-11D1-A28C-00C04FB94F17", gpo_snapin_handler_none }, + { NULL, NULL, NULL } +}; + +static const char *name_to_guid_string(const char *name, struct gpo_table *table) +{ + int i; + + for (i = 0; table[i].name; i++) { + if (strequal(name, table[i].name)) { + return table[i].guid_string; + } + } + + return NULL; +} + +static const char *guid_string_to_name(const char *guid_string, struct gpo_table *table) +{ + int i; + + for (i = 0; table[i].guid_string; i++) { + if (strequal(guid_string, table[i].guid_string)) { + return table[i].name; + } + } + + return NULL; +} + +static const char *default_gpo_name_to_guid_string(const char *name) +{ + return name_to_guid_string(name, gpo_default_policy); +} + +static const char *default_gpo_guid_string_to_name(const char *guid) +{ + return guid_string_to_name(guid, gpo_default_policy); +} + +const char *cse_gpo_guid_string_to_name(const char *guid) +{ + return guid_string_to_name(guid, gpo_cse_extensions); +} + +static const char *cse_gpo_name_to_guid_string(const char *name) +{ + return name_to_guid_string(name, gpo_cse_extensions); +} + +const char *cse_snapin_gpo_guid_string_to_name(const char *guid) +{ + return guid_string_to_name(guid, gpo_cse_snapin_extensions); +} + +void dump_gp_ext(struct GP_EXT *gp_ext) +{ + int lvl = 10; + int i; + + if (gp_ext == NULL) { + return; + } + + DEBUG(lvl,("---------------------\n\n")); + DEBUGADD(lvl,("name:\t\t\t%s\n", gp_ext->gp_extension)); + + for (i=0; i< gp_ext->num_exts; i++) { + + DEBUGADD(lvl,("extension:\t\t\t%s\n", gp_ext->extensions_guid[i])); + DEBUGADD(lvl,("extension (name):\t\t\t%s\n", gp_ext->extensions[i])); + + DEBUGADD(lvl,("snapin:\t\t\t%s\n", gp_ext->snapins_guid[i])); + DEBUGADD(lvl,("snapin (name):\t\t\t%s\n", gp_ext->snapins[i])); + } +} + +void dump_gpo(TALLOC_CTX *mem_ctx, struct GROUP_POLICY_OBJECT *gpo) +{ + int lvl = 1; + + if (gpo == NULL) { + return; + } + + DEBUG(lvl,("---------------------\n\n")); + + DEBUGADD(lvl,("name:\t\t\t%s\n", gpo->name)); + DEBUGADD(lvl,("displayname:\t\t%s\n", gpo->display_name)); + DEBUGADD(lvl,("version:\t\t%d (0x%08x)\n", gpo->version, gpo->version)); + DEBUGADD(lvl,("version_user:\t\t%d (0x%04x)\n", gpo->version_user, gpo->version_user)); + DEBUGADD(lvl,("version_machine:\t%d (0x%04x)\n", gpo->version_machine, gpo->version_machine)); + DEBUGADD(lvl,("filesyspath:\t\t%s\n", gpo->file_sys_path)); + DEBUGADD(lvl,("dspath:\t\t%s\n", gpo->ds_path)); + + DEBUGADD(lvl,("options:\t\t%d ", gpo->options)); + if (gpo->options & GPFLAGS_USER_SETTINGS_DISABLED) { + DEBUGADD(lvl,("GPFLAGS_USER_SETTINGS_DISABLED ")); + } + if (gpo->options & GPFLAGS_MACHINE_SETTINGS_DISABLED) { + DEBUGADD(lvl,("GPFLAGS_MACHINE_SETTINGS_DISABLED")); + } + DEBUGADD(lvl,("\n")); + + DEBUGADD(lvl,("link:\t\t\t%s\n", gpo->link)); + DEBUGADD(lvl,("link_type:\t\t%d ", gpo->link_type)); + switch (gpo->link_type) { + case GP_LINK_UNKOWN: + DEBUGADD(lvl,("GP_LINK_UNKOWN\n")); + break; + case GP_LINK_OU: + DEBUGADD(lvl,("GP_LINK_OU\n")); + break; + case GP_LINK_DOMAIN: + DEBUGADD(lvl,("GP_LINK_DOMAIN\n")); + break; + case GP_LINK_SITE: + DEBUGADD(lvl,("GP_LINK_SITE\n")); + break; + case GP_LINK_MACHINE: + DEBUGADD(lvl,("GP_LINK_MACHINE\n")); + break; + default: + break; + } + + if (gpo->machine_extensions) { + + struct GP_EXT gp_ext; + ADS_STATUS status; + + DEBUGADD(lvl,("machine_extensions:\t%s\n", gpo->machine_extensions)); + + status = ads_parse_gp_ext(mem_ctx, gpo->machine_extensions, &gp_ext); + if (!ADS_ERR_OK(status)) { + return; + } + dump_gp_ext(&gp_ext); + } + + if (gpo->user_extensions) { + + struct GP_EXT gp_ext; + ADS_STATUS status; + + DEBUGADD(lvl,("user_extensions:\t%s\n", gpo->user_extensions)); + + status = ads_parse_gp_ext(mem_ctx, gpo->user_extensions, &gp_ext); + if (!ADS_ERR_OK(status)) { + return; + } + dump_gp_ext(&gp_ext); + } +}; + +void dump_gplink(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, struct GP_LINK *gp_link) +{ + ADS_STATUS status; + int i; + int lvl = 10; + + if (gp_link == NULL) { + return; + } + + DEBUG(lvl,("---------------------\n\n")); + + DEBUGADD(lvl,("gplink: %s\n", gp_link->gp_link)); + DEBUGADD(lvl,("gpopts: %d ", gp_link->gp_opts)); + switch (gp_link->gp_opts) { + case GPOPTIONS_INHERIT: + DEBUGADD(lvl,("GPOPTIONS_INHERIT\n")); + break; + case GPOPTIONS_BLOCK_INHERITANCE: + DEBUGADD(lvl,("GPOPTIONS_BLOCK_INHERITANCE\n")); + break; + default: + break; + } + + DEBUGADD(lvl,("num links: %d\n", gp_link->num_links)); + + for (i = 0; i < gp_link->num_links; i++) { + + DEBUGADD(lvl,("---------------------\n\n")); + + DEBUGADD(lvl,("link: #%d\n", i + 1)); + DEBUGADD(lvl,("name: %s\n", gp_link->link_names[i])); + + DEBUGADD(lvl,("opt: %d ", gp_link->link_opts[i])); + if (gp_link->link_opts[i] & GPO_LINK_OPT_ENFORCED) { + DEBUGADD(lvl,("GPO_LINK_OPT_ENFORCED ")); + } + if (gp_link->link_opts[i] & GPO_LINK_OPT_DISABLED) { + DEBUGADD(lvl,("GPO_LINK_OPT_DISABLED")); + } + DEBUGADD(lvl,("\n")); + + if (ads != NULL && mem_ctx != NULL) { + + struct GROUP_POLICY_OBJECT gpo; + + status = ads_get_gpo(ads, mem_ctx, gp_link->link_names[i], NULL, NULL, &gpo); + if (!ADS_ERR_OK(status)) { + DEBUG(lvl,("get gpo for %s failed: %s\n", gp_link->link_names[i], ads_errstr(status))); + return; + } + dump_gpo(mem_ctx, &gpo); + } + } +} + +ADS_STATUS process_extension_with_snapin(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + const char *extension_guid, + const char *snapin_guid) +{ + int i; + + for (i=0; gpo_cse_snapin_extensions[i].guid_string; i++) { + + if (strcmp(gpo_cse_snapin_extensions[i].guid_string, snapin_guid) == 0) { + + return gpo_cse_snapin_extensions[i].snapin_fn(ads, mem_ctx, + extension_guid, snapin_guid); + } + } + + DEBUG(10,("process_extension_with_snapin: no snapin handler for extension %s (%s) found\n", + extension_guid, snapin_guid)); + + return ADS_ERROR(LDAP_SUCCESS); +} + +ADS_STATUS gpo_process_a_gpo(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + struct GROUP_POLICY_OBJECT *gpo, + const char *extension_guid, + uint32 flags) +{ + ADS_STATUS status; + struct GP_EXT gp_ext; + int i; + + if (flags & GPO_LIST_FLAG_MACHINE) { + + if (gpo->machine_extensions) { + + status = ads_parse_gp_ext(mem_ctx, gpo->machine_extensions, &gp_ext); + + if (!ADS_ERR_OK(status)) { + return status; + } + + } else { + /* nothing to apply */ + return ADS_ERROR(LDAP_SUCCESS); + } + + } else { + + if (gpo->user_extensions) { + + status = ads_parse_gp_ext(mem_ctx, gpo->user_extensions, &gp_ext); + + if (!ADS_ERR_OK(status)) { + return status; + } + } else { + /* nothing to apply */ + return ADS_ERROR(LDAP_SUCCESS); + } + } + + for (i=0; inext) { + + status = gpo_process_a_gpo(ads, mem_ctx, gpo, + extensions_guid, flags); + + if (!ADS_ERR_OK(status)) { + return status; + } + + } + + return ADS_ERROR(LDAP_SUCCESS); +} + +ADS_STATUS gpo_snapin_handler_none(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + const char *extension_guid, + const char *snapin_guid) +{ + DEBUG(10,("gpo_snapin_handler_none\n")); + + return ADS_ERROR(LDAP_SUCCESS); +} + +ADS_STATUS gpo_snapin_handler_security_settings(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + const char *extension_guid, + const char *snapin_guid) +{ + DEBUG(10,("gpo_snapin_handler_security_settings\n")); + + return ADS_ERROR(LDAP_SUCCESS); +} + +ADS_STATUS gpo_lockout_policy(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + const char *hostname, + SAM_UNK_INFO_12 *lockout_policy) +{ + return ADS_ERROR_NT(NT_STATUS_NOT_IMPLEMENTED); +} + +ADS_STATUS gpo_password_policy(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + const char *hostname, + SAM_UNK_INFO_1 *password_policy) +{ + ADS_STATUS status; + struct GROUP_POLICY_OBJECT *gpo_list; + const char *attrs[] = {"distinguishedName", "userAccountControl", NULL}; + char *filter, *dn; + void *res = NULL; + uint32 uac; + + return ADS_ERROR_NT(NT_STATUS_NOT_IMPLEMENTED); + + filter = talloc_asprintf(mem_ctx, "(&(objectclass=user)(sAMAccountName=%s))", hostname); + if (filter == NULL) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + + status = ads_do_search_all(ads, ads->config.bind_path, + LDAP_SCOPE_SUBTREE, + filter, attrs, &res); + + if (!ADS_ERR_OK(status)) { + return status; + } + + if (ads_count_replies(ads, res) != 1) { + return ADS_ERROR(LDAP_NO_SUCH_OBJECT); + } + + dn = ads_get_dn(ads, res); + if (dn == NULL) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + + if (!ads_pull_uint32(ads, res, "userAccountControl", &uac)) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + + if (!(uac & UF_WORKSTATION_TRUST_ACCOUNT)) { + return ADS_ERROR(LDAP_NO_SUCH_OBJECT); + } + + status = ads_get_gpo_list(ads, mem_ctx, dn, GPO_LIST_FLAG_MACHINE, &gpo_list); + if (!ADS_ERR_OK(status)) { + return status; + } + + status = gpo_process_gpo_list(ads, mem_ctx, &gpo_list, + cse_gpo_name_to_guid_string("Security"), + GPO_LIST_FLAG_MACHINE); + if (!ADS_ERR_OK(status)) { + return status; + } + + return ADS_ERROR(LDAP_SUCCESS); +} diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index d5b4b11fa2..67f8433775 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -62,13 +62,17 @@ int kerberos_kinit_password(const char *principal, const char *password, int time_offset, time_t *expire_time, - const char *cache_name) + time_t *renew_till_time, + const char *cache_name, + BOOL request_pac, + time_t renewable_time) { krb5_context ctx = NULL; krb5_error_code code = 0; krb5_ccache cc = NULL; krb5_principal me; krb5_creds my_creds; + krb5_get_init_creds_opt opt; initialize_krb5_error_table(); if ((code = krb5_init_context(&ctx))) @@ -77,9 +81,11 @@ int kerberos_kinit_password(const char *principal, if (time_offset != 0) { krb5_set_real_time(ctx, time(NULL) + time_offset, 0); } - - if ((code = krb5_cc_resolve(ctx, cache_name ? - cache_name : krb5_cc_default_name(ctx), &cc))) { + + DEBUG(10,("kerberos_kinit_password: using %s as ccache\n", + cache_name ? cache_name: krb5_cc_default_name(ctx))); + + if ((code = krb5_cc_resolve(ctx, cache_name ? cache_name : krb5_cc_default_name(ctx), &cc))) { krb5_free_context(ctx); return code; } @@ -88,10 +94,20 @@ int kerberos_kinit_password(const char *principal, krb5_free_context(ctx); return code; } + + krb5_get_init_creds_opt_init(&opt); + krb5_get_init_creds_opt_set_renew_life(&opt, renewable_time); + krb5_get_init_creds_opt_set_forwardable(&opt, 1); + if (request_pac) { +#ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PAC_REQUEST + krb5_get_init_creds_opt_set_pac_request(ctx, &opt, True); +#endif + } + if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, CONST_DISCARD(char *,password), kerb_prompter, - NULL, 0, NULL, NULL))) { + NULL, 0, NULL, &opt))) { krb5_free_principal(ctx, me); krb5_free_context(ctx); return code; @@ -111,9 +127,14 @@ int kerberos_kinit_password(const char *principal, krb5_free_context(ctx); return code; } - - if (expire_time) + + if (expire_time) { *expire_time = (time_t) my_creds.times.endtime; + } + + if (renew_till_time) { + *renew_till_time = (time_t) my_creds.times.renew_till; + } krb5_cc_close(ctx, cc); krb5_free_cred_contents(ctx, &my_creds); @@ -157,7 +178,7 @@ int ads_kinit_password(ADS_STRUCT *ads) } ret = kerberos_kinit_password(s, ads->auth.password, ads->auth.time_offset, - &ads->auth.expire, NULL); + &ads->auth.expire, NULL, NULL, False, ads->auth.renewable); if (ret) { DEBUG(0,("kerberos_kinit_password %s failed: %s\n", @@ -349,7 +370,8 @@ static krb5_error_code get_service_ticket(krb5_context ctx, if (password == NULL) { goto out; } - if ((err = kerberos_kinit_password(machine_account, password, 0, NULL, LIBADS_CCACHE_NAME)) != 0) { + if ((err = kerberos_kinit_password(machine_account, password, 0, NULL, NULL, + LIBADS_CCACHE_NAME, False, 0)) != 0) { DEBUG(0,("get_service_ticket: kerberos_kinit_password %s@%s failed: %s\n", machine_account, lp_realm(), diff --git a/source3/libads/krb5_errs.c b/source3/libads/krb5_errs.c new file mode 100644 index 0000000000..cd227d4377 --- /dev/null +++ b/source3/libads/krb5_errs.c @@ -0,0 +1,132 @@ +/* + * Unix SMB/CIFS implementation. + * Kerberos error mapping functions + * Copyright (C) Guenther Deschner 2005 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "includes.h" + +#ifdef HAVE_KRB5 + +static const struct { + int krb5_code; + NTSTATUS ntstatus; +} krb5_to_nt_status_map[] = { + {KRB5_CC_IO, NT_STATUS_UNEXPECTED_IO_ERROR}, + {KRB5KDC_ERR_BADOPTION, NT_STATUS_INVALID_PARAMETER}, + {KRB5KDC_ERR_CLIENT_REVOKED, NT_STATUS_ACCESS_DENIED}, + {KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN, NT_STATUS_INVALID_ACCOUNT_NAME}, + {KRB5KDC_ERR_ETYPE_NOSUPP, NT_STATUS_LOGON_FAILURE}, +#if defined(KRB5KDC_ERR_KEY_EXPIRED) /* Heimdal */ + {KRB5KDC_ERR_KEY_EXPIRED, NT_STATUS_PASSWORD_EXPIRED}, +#elif defined(KRB5KDC_ERR_KEY_EXP) /* MIT */ + {KRB5KDC_ERR_KEY_EXP, NT_STATUS_PASSWORD_EXPIRED}, +#else +#error Neither KRB5KDC_ERR_KEY_EXPIRED nor KRB5KDC_ERR_KEY_EXP available +#endif + {25, NT_STATUS_PASSWORD_EXPIRED}, /* FIXME: bug in heimdal 0.7 krb5_get_init_creds_password (Inappropriate ioctl for device (25)) */ + {KRB5KDC_ERR_NULL_KEY, NT_STATUS_LOGON_FAILURE}, + {KRB5KDC_ERR_POLICY, NT_STATUS_PASSWORD_RESTRICTION}, + {KRB5KDC_ERR_PREAUTH_FAILED, NT_STATUS_LOGON_FAILURE}, + {KRB5KDC_ERR_SERVICE_REVOKED, NT_STATUS_ACCESS_DENIED}, + {KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN, NT_STATUS_INVALID_ACCOUNT_NAME}, + {KRB5KDC_ERR_SUMTYPE_NOSUPP, NT_STATUS_LOGON_FAILURE}, + {KRB5KDC_ERR_TGT_REVOKED, NT_STATUS_ACCESS_DENIED}, + {KRB5_KDC_UNREACH, NT_STATUS_NO_LOGON_SERVERS}, + {KRB5KRB_AP_ERR_BAD_INTEGRITY, NT_STATUS_LOGON_FAILURE}, + {KRB5KRB_AP_ERR_MODIFIED, NT_STATUS_LOGON_FAILURE}, + {KRB5KRB_AP_ERR_SKEW, NT_STATUS_TIME_DIFFERENCE_AT_DC}, + {KRB5KRB_AP_ERR_TKT_EXPIRED, NT_STATUS_LOGON_FAILURE}, + {KRB5KRB_ERR_GENERIC, NT_STATUS_UNSUCCESSFUL}, + {KRB5KRB_ERR_RESPONSE_TOO_BIG, NT_STATUS_PROTOCOL_UNREACHABLE}, + {0, NT_STATUS_OK} +}; + +static const struct { + NTSTATUS ntstatus; + int krb5_code; +} nt_status_to_krb5_map[] = { + {NT_STATUS_LOGON_FAILURE, KRB5KDC_ERR_PREAUTH_FAILED}, + {NT_STATUS_NO_LOGON_SERVERS, KRB5_KDC_UNREACH}, + {NT_STATUS_OK, 0} +}; + +/***************************************************************************** +convert a KRB5 error to a NT status32 code + *****************************************************************************/ +NTSTATUS krb5_to_nt_status(int kerberos_error) +{ + int i; + + if (kerberos_error == 0) { + return NT_STATUS_OK; + } + + for (i=0; NT_STATUS_V(krb5_to_nt_status_map[i].ntstatus); i++) { + if (kerberos_error == krb5_to_nt_status_map[i].krb5_code) + return krb5_to_nt_status_map[i].ntstatus; + } + + return NT_STATUS_UNSUCCESSFUL; +} + +/***************************************************************************** +convert an NT status32 code to a KRB5 error + *****************************************************************************/ +int nt_status_to_krb5(NTSTATUS nt_status) +{ + int i; + + if NT_STATUS_IS_OK(nt_status) { + return 0; + } + + for (i=0; NT_STATUS_V(nt_status_to_krb5_map[i].ntstatus); i++) { + if (NT_STATUS_EQUAL(nt_status,nt_status_to_krb5_map[i].ntstatus)) + return nt_status_to_krb5_map[i].krb5_code; + } + + return KRB5KRB_ERR_GENERIC; +} + +#else + +/***************************************************************************** +convert a KRB5 error to a NT status32 code + *****************************************************************************/ +NTSTATUS krb5_to_nt_status(int kerberos_error) +{ + if (kerberos_error == 0) { + return NT_STATUS_OK; + } + + return NT_STATUS_UNSUCCESSFUL; +} + +/***************************************************************************** +convert an NT status32 code to a KRB5 error + *****************************************************************************/ +int nt_status_to_krb5(NTSTATUS nt_status) +{ + if (NT_STATUS_EQUAL(nt_status, NT_STATUS_OK)) { + return 0; + } + return -1; /* FIXME: what to return here ? */ +} + +#endif + diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 31d0a02cad..6ffd218e96 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -24,9 +24,17 @@ #ifdef HAVE_KRB5 #define DEFAULT_KPASSWD_PORT 464 + #define KRB5_KPASSWD_VERS_CHANGEPW 1 + #define KRB5_KPASSWD_VERS_SETPW 0xff80 #define KRB5_KPASSWD_VERS_SETPW_ALT 2 + +#define KRB5_KPASSWD_SUCCESS 0 +#define KRB5_KPASSWD_MALFORMED 1 +#define KRB5_KPASSWD_HARDERROR 2 +#define KRB5_KPASSWD_AUTHERROR 3 +#define KRB5_KPASSWD_SOFTERROR 4 #define KRB5_KPASSWD_ACCESSDENIED 5 #define KRB5_KPASSWD_BAD_VERSION 6 #define KRB5_KPASSWD_INITIAL_FLAG_NEEDED 7 @@ -213,6 +221,25 @@ static krb5_error_code setpw_result_code_string(krb5_context context, return (0); } + krb5_error_code kpasswd_err_to_krb5_err(krb5_error_code res_code) +{ + switch(res_code) { + case KRB5_KPASSWD_ACCESSDENIED: + return KRB5KDC_ERR_BADOPTION; + case KRB5_KPASSWD_INITIAL_FLAG_NEEDED: + return KRB5KDC_ERR_BADOPTION; + /* return KV5M_ALT_METHOD; MIT-only define */ + case KRB5_KPASSWD_ETYPE_NOSUPP: + return KRB5KDC_ERR_ETYPE_NOSUPP; + case KRB5_KPASSWD_BAD_PRINCIPAL: + return KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN; + case KRB5_KPASSWD_POLICY_REJECT: + case KRB5_KPASSWD_SOFTERROR: + return KRB5KDC_ERR_POLICY; + default: + return KRB5KRB_ERR_GENERIC; + } +} static krb5_error_code parse_setpw_reply(krb5_context context, krb5_auth_context auth_context, krb5_data *packet) @@ -312,23 +339,9 @@ static krb5_error_code parse_setpw_reply(krb5_context context, else { const char *errstr; setpw_result_code_string(context, res_code, &errstr); - DEBUG(1, ("Error changing password: %s\n", errstr)); - - switch(res_code) { - case KRB5_KPASSWD_ACCESSDENIED: - return KRB5KDC_ERR_BADOPTION; - case KRB5_KPASSWD_INITIAL_FLAG_NEEDED: - return KRB5KDC_ERR_BADOPTION; - /* return KV5M_ALT_METHOD; MIT-only define */ - case KRB5_KPASSWD_ETYPE_NOSUPP: - return KRB5KDC_ERR_ETYPE_NOSUPP; - case KRB5_KPASSWD_BAD_PRINCIPAL: - return KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN; - case KRB5_KPASSWD_POLICY_REJECT: - return KRB5KDC_ERR_POLICY; - default: - return KRB5KRB_ERR_GENERIC; - } + DEBUG(1, ("Error changing password: %s (%d)\n", errstr, res_code)); + + return kpasswd_err_to_krb5_err(res_code); } } @@ -664,7 +677,7 @@ ADS_STATUS kerberos_set_password(const char *kpasswd_server, { int ret; - if ((ret = kerberos_kinit_password(auth_principal, auth_password, time_offset, NULL, NULL))) { + if ((ret = kerberos_kinit_password(auth_principal, auth_password, time_offset, NULL, NULL, NULL, False, 0))) { DEBUG(1,("Failed kinit for principal %s (%s)\n", auth_principal, error_message(ret))); return ADS_ERROR_KRB5(ret); } diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index e503da62a4..8444989bac 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -4,6 +4,7 @@ Copyright (C) Andrew Tridgell 2001 Copyright (C) Remus Koos 2001 Copyright (C) Jim McDonough 2002 + Copyright (C) Guenther Deschner 2005 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -807,6 +808,65 @@ char *ads_get_dn(ADS_STRUCT *ads, void *msg) return unix_dn; } +/** + * Get a canonical dn from search results + * @param ads connection to ads server + * @param msg Search result + * @return dn string + **/ +char *ads_get_dn_canonical(ADS_STRUCT *ads, void *msg) +{ +#ifdef HAVE_LDAP_DN2AD_CANONICAL + return ldap_dn2ad_canonical(ads_get_dn(ads, msg)); +#else + return NULL; +#endif +} + + +/** + * Get the parent dn from a search result + * @param ads connection to ads server + * @param msg Search result + * @return parent dn string + **/ +char *ads_get_parent_dn(ADS_STRUCT *ads, void *msg) +{ + char *mydn, *p, *dn; + + dn = ads_get_dn(ads, msg); + if (dn == NULL) { + return NULL; + } + + mydn = dn; + ads_memfree(ads, dn); + + p = strchr(mydn, ','); + + if (p == NULL) { + return NULL; + } + + return p+1; +} + +/** + * Get the parent from a dn + * @param dn the dn to return the parent from + * @return parent dn string + **/ +char *ads_parent_dn(const char *dn) +{ + char *p = strchr(dn, ','); + + if (p == NULL) { + return NULL; + } + + return p+1; +} + /** * Find a machine account given a hostname * @param ads connection to ads server @@ -2700,4 +2760,167 @@ ADS_STATUS ads_workgroup_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char * return ADS_SUCCESS; } +/** + * find our site name + * @param ads connection to ads server + * @param mem_ctx Pointer to talloc context + * @param site_name Pointer to the sitename + * @return status of search + **/ +ADS_STATUS ads_site_dn(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char **site_name) +{ + ADS_STATUS status; + void *res; + const char *dn, *service_name; + const char *attrs[] = { "dsServiceName", NULL }; + + status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); + if (!ADS_ERR_OK(status)) { + return status; + } + + service_name = ads_pull_string(ads, mem_ctx, res, "dsServiceName"); + if (service_name == NULL) { + return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); + } + + /* go up three levels */ + dn = ads_parent_dn(ads_parent_dn(ads_parent_dn(service_name))); + if (dn == NULL) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + + *site_name = talloc_strdup(mem_ctx, dn); + if (*site_name == NULL) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + + ads_msgfree(ads, res); + + return status; + /* + dsServiceName: CN=NTDS Settings,CN=W2K3DC,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=ber,DC=suse,DC=de + */ +} + +/** + * find the site dn where a machine resides + * @param ads connection to ads server + * @param mem_ctx Pointer to talloc context + * @param computer_name name of the machine + * @param site_name Pointer to the sitename + * @return status of search + **/ +ADS_STATUS ads_site_dn_for_machine(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char *computer_name, const char **site_dn) +{ + ADS_STATUS status; + void *res; + const char *parent, *config_context, *filter; + const char *attrs[] = { "configurationNamingContext", NULL }; + char *dn; + + /* shortcut a query */ + if (strequal(computer_name, ads->config.ldap_server_name)) { + return ads_site_dn(ads, mem_ctx, site_dn); + } + + status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); + if (!ADS_ERR_OK(status)) { + return status; + } + + config_context = ads_pull_string(ads, mem_ctx, res, "configurationNamingContext"); + if (config_context == NULL) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + + filter = talloc_asprintf(mem_ctx, "(cn=%s)", computer_name); + if (filter == NULL) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + + status = ads_do_search(ads, config_context, LDAP_SCOPE_SUBTREE, filter, NULL, &res); + if (!ADS_ERR_OK(status)) { + return status; + } + + if (ads_count_replies(ads, res) != 1) { + return ADS_ERROR(LDAP_NO_SUCH_OBJECT); + } + + dn = ads_get_dn(ads, res); + if (dn == NULL) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + + /* go up three levels */ + parent = ads_parent_dn(ads_parent_dn(ads_parent_dn(dn))); + if (parent == NULL) { + ads_memfree(ads, dn); + return ADS_ERROR(LDAP_NO_MEMORY); + } + + *site_dn = talloc_strdup(mem_ctx, parent); + if (*site_dn == NULL) { + ads_memfree(ads, dn); + ADS_ERROR(LDAP_NO_MEMORY); + } + + ads_memfree(ads, dn); + ads_msgfree(ads, res); + + return status; +} + +/** + * get the upn suffixes for a domain + * @param ads connection to ads server + * @param mem_ctx Pointer to talloc context + * @param suffixes Pointer to an array of suffixes + * @param site_name Pointer to the number of suffixes + * @return status of search + **/ +ADS_STATUS ads_upn_suffixes(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char **suffixes, size_t *num_suffixes) +{ + ADS_STATUS status; + void *res; + const char *config_context, *base; + const char *attrs[] = { "configurationNamingContext", NULL }; + const char *attrs2[] = { "uPNSuffixes", NULL }; + + status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); + if (!ADS_ERR_OK(status)) { + return status; + } + + config_context = ads_pull_string(ads, mem_ctx, res, "configurationNamingContext"); + if (config_context == NULL) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + + base = talloc_asprintf(mem_ctx, "cn=Partitions,%s", config_context); + if (base == NULL) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + + status = ads_search_dn(ads, &res, base, attrs2); + if (!ADS_ERR_OK(status)) { + return status; + } + + if (ads_count_replies(ads, res) != 1) { + return ADS_ERROR(LDAP_NO_SUCH_OBJECT); + } + + suffixes = ads_pull_strings(ads, mem_ctx, &res, "uPNSuffixes", num_suffixes); + if (suffixes == NULL) { + ads_msgfree(ads, res); + return ADS_ERROR(LDAP_NO_MEMORY); + } + + ads_msgfree(ads, res); + + return status; +} + #endif diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index f6adfb5108..d8d33a924f 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -294,16 +294,28 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) /* we need to fetch a service ticket as the ldap user in the servers realm, regardless of our realm */ asprintf(&sname, "ldap/%s@%s", ads->config.ldap_server_name, ads->config.realm); - krb5_init_context(&ctx); - krb5_set_default_tgs_ktypes(ctx, enc_types); - krb5_parse_name(ctx, sname, &principal); + + initialize_krb5_error_table(); + status = ADS_ERROR_KRB5(krb5_init_context(&ctx)); + if (!ADS_ERR_OK(status)) { + return status; + } + status = ADS_ERROR_KRB5(krb5_set_default_tgs_ktypes(ctx, enc_types)); + if (!ADS_ERR_OK(status)) { + return status; + } + status = ADS_ERROR_KRB5(krb5_parse_name(ctx, sname, &principal)); + if (!ADS_ERR_OK(status)) { + return status; + } + free(sname); krb5_free_context(ctx); input_name.value = &principal; input_name.length = sizeof(principal); - gss_rc = gss_import_name(&minor_status,&input_name,&nt_principal, &serv_name); + gss_rc = gss_import_name(&minor_status, &input_name, &nt_principal, &serv_name); if (gss_rc) { return ADS_ERROR_GSS(gss_rc, minor_status); } @@ -375,8 +387,9 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) p = (uint8 *)output_token.value; +#if 0 file_save("sasl_gssapi.dat", output_token.value, output_token.length); - +#endif max_msg_size = (p[1]<<16) | (p[2]<<8) | p[3]; sec_layer = *p; -- cgit From c1ffb8d9bcad9053f3d97dc89c3ff3b023401157 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 9 Feb 2006 10:24:27 +0000 Subject: r13410: Dump a netbootGUID as a GUID. Guenther (This used to be commit 9b19a68456c7b576750aaf64c178ba5323d9a95e) --- source3/libads/ldap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 8444989bac..6d2155fae0 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1684,6 +1684,7 @@ static BOOL ads_dump_field(char *field, void **values, void *data_area) void (*handler)(const char *, struct berval **); } handlers[] = { {"objectGUID", False, dump_guid}, + {"netbootGUID", False, dump_guid}, {"nTSecurityDescriptor", False, dump_sd}, {"dnsRecord", False, dump_binary}, {"objectSid", False, dump_sid}, -- cgit From 4ea92f30985466489a3b3faf5a1c90667175aad6 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 20 Feb 2006 23:22:56 +0000 Subject: r13581: Correctly parse a non-null terminated, little-endian UCS2 string in the PAC_LOGON_NAME structure. This was broken on big-endian machines (Solaris SPARC and ppc). Fixes Bug #3330. Jerry, this should be in 3.0.21c. Guenther (This used to be commit 9732490811f8f02ee547ddc6e2694e1122a3a518) --- source3/libads/authdata.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c index 55e736ce6a..bb4236c4fc 100644 --- a/source3/libads/authdata.c +++ b/source3/libads/authdata.c @@ -42,16 +42,7 @@ static BOOL pac_io_logon_name(const char *desc, PAC_LOGON_NAME *logon_name, if (!prs_uint16("len", ps, depth, &logon_name->len)) return False; - if (UNMARSHALLING(ps) && logon_name->len) { - logon_name->username = PRS_ALLOC_MEM(ps, uint16, logon_name->len); - if (!logon_name->username) { - DEBUG(3, ("No memory available\n")); - return False; - } - } - - if (!prs_uint16s(True, "name", ps, depth, logon_name->username, - (logon_name->len / sizeof(uint16)))) + if (!prs_string_len("name", ps, depth, logon_name->username, logon_name->len)) return False; return True; @@ -891,7 +882,8 @@ static void dump_pac_logon_info(PAC_LOGON_INFO *logon_info) { nt_status = NT_STATUS_INVALID_PARAMETER; goto out; } - rpcstr_pull(username, logon_name->username, sizeof(username), -1, STR_TERMINATE); + + rpcstr_pull(username, logon_name->username, sizeof(username), logon_name->len, 0); ret = smb_krb5_parse_name_norealm(context, username, &client_principal_pac); if (ret) { -- cgit From 115996503ced64c478ed1cc857bd5a1528644b46 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 21 Feb 2006 03:08:42 +0000 Subject: r13585: Sorry Gunther, had to revert this. It's got a buffer overrun. Spoke to Jerry about the correct fix. Will add this after. Jeremy. (This used to be commit 33e13aabd3825c59d15dc897536e2ccf8c8f6d5e) --- source3/libads/authdata.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c index bb4236c4fc..55e736ce6a 100644 --- a/source3/libads/authdata.c +++ b/source3/libads/authdata.c @@ -42,7 +42,16 @@ static BOOL pac_io_logon_name(const char *desc, PAC_LOGON_NAME *logon_name, if (!prs_uint16("len", ps, depth, &logon_name->len)) return False; - if (!prs_string_len("name", ps, depth, logon_name->username, logon_name->len)) + if (UNMARSHALLING(ps) && logon_name->len) { + logon_name->username = PRS_ALLOC_MEM(ps, uint16, logon_name->len); + if (!logon_name->username) { + DEBUG(3, ("No memory available\n")); + return False; + } + } + + if (!prs_uint16s(True, "name", ps, depth, logon_name->username, + (logon_name->len / sizeof(uint16)))) return False; return True; @@ -882,8 +891,7 @@ static void dump_pac_logon_info(PAC_LOGON_INFO *logon_info) { nt_status = NT_STATUS_INVALID_PARAMETER; goto out; } - - rpcstr_pull(username, logon_name->username, sizeof(username), logon_name->len, 0); + rpcstr_pull(username, logon_name->username, sizeof(username), -1, STR_TERMINATE); ret = smb_krb5_parse_name_norealm(context, username, &client_principal_pac); if (ret) { -- cgit From a57f37420b2b41b1905e2eefa385036b9ddb5bcf Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 21 Feb 2006 03:29:02 +0000 Subject: r13588: Second attempt to fix Bug #3330 - treat the string as a uint8 array and copy as such. Gunther please check (sorry I reverted your earlier fix). Jeremy. (This used to be commit 7a17b39c80703909f102487690d2117d874b0e15) --- source3/libads/authdata.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c index 55e736ce6a..c3c160dafb 100644 --- a/source3/libads/authdata.c +++ b/source3/libads/authdata.c @@ -42,24 +42,24 @@ static BOOL pac_io_logon_name(const char *desc, PAC_LOGON_NAME *logon_name, if (!prs_uint16("len", ps, depth, &logon_name->len)) return False; + /* The following string is always in little endian 16 bit values, + copy as 8 bits to avoid endian reversal on big-endian machines. + len is the length in bytes. */ + if (UNMARSHALLING(ps) && logon_name->len) { - logon_name->username = PRS_ALLOC_MEM(ps, uint16, logon_name->len); + logon_name->username = PRS_ALLOC_MEM(ps, uint8, logon_name->len); if (!logon_name->username) { DEBUG(3, ("No memory available\n")); return False; } } - if (!prs_uint16s(True, "name", ps, depth, logon_name->username, - (logon_name->len / sizeof(uint16)))) + if (!prs_uint8s(True, "name", ps, depth, logon_name->username, logon_name->len)) return False; return True; - } - - #if 0 /* Unused (handled now in net_io_user_info3()) - Guenther */ static BOOL pac_io_krb_sids(const char *desc, KRB_SID_AND_ATTRS *sid_and_attr, prs_struct *ps, int depth) @@ -891,7 +891,7 @@ static void dump_pac_logon_info(PAC_LOGON_INFO *logon_info) { nt_status = NT_STATUS_INVALID_PARAMETER; goto out; } - rpcstr_pull(username, logon_name->username, sizeof(username), -1, STR_TERMINATE); + rpcstr_pull(username, logon_name->username, sizeof(username), logon_name->len, 0); ret = smb_krb5_parse_name_norealm(context, username, &client_principal_pac); if (ret) { -- cgit From 3c892fdf4f5a33801762e3faa403d2ecb5c1b574 Mon Sep 17 00:00:00 2001 From: Lars Müller Date: Tue, 21 Feb 2006 17:19:20 +0000 Subject: r13597: krb5 error codes are defined as long. (This used to be commit bab8c156a464c1beaa022e0026184e0de84c0bf9) --- source3/libads/krb5_errs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/krb5_errs.c b/source3/libads/krb5_errs.c index cd227d4377..f926024b72 100644 --- a/source3/libads/krb5_errs.c +++ b/source3/libads/krb5_errs.c @@ -23,7 +23,7 @@ #ifdef HAVE_KRB5 static const struct { - int krb5_code; + long krb5_code; NTSTATUS ntstatus; } krb5_to_nt_status_map[] = { {KRB5_CC_IO, NT_STATUS_UNEXPECTED_IO_ERROR}, -- cgit From 0eb50d9016d130217df3d56b9c666468f7cff58b Mon Sep 17 00:00:00 2001 From: Lars Müller Date: Tue, 21 Feb 2006 17:48:20 +0000 Subject: r13599: krb5 error codes are defined as long. Also for the other direction. (This used to be commit 7b8ea1499124d1e1efe325339419a66ab8885b38) --- source3/libads/krb5_errs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/krb5_errs.c b/source3/libads/krb5_errs.c index f926024b72..0277596436 100644 --- a/source3/libads/krb5_errs.c +++ b/source3/libads/krb5_errs.c @@ -58,7 +58,7 @@ static const struct { static const struct { NTSTATUS ntstatus; - int krb5_code; + long krb5_code; } nt_status_to_krb5_map[] = { {NT_STATUS_LOGON_FAILURE, KRB5KDC_ERR_PREAUTH_FAILED}, {NT_STATUS_NO_LOGON_SERVERS, KRB5_KDC_UNREACH}, -- cgit From 379bd6865f2fa46ea28024ad2bb2162ccfbb0db7 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 23 Feb 2006 14:28:41 +0000 Subject: r13657: Let winbindd try to obtain the gecos field from the msSFU30Gecos attribute when "winbind nss info = sfu" is set. Fixes #3539. Guenther (This used to be commit ffce0461de130828345c44293e564ca03227607d) --- source3/libads/ads_struct.c | 1 + source3/libads/ldap.c | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index d8676d050d..9b2179ad31 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -139,6 +139,7 @@ void ads_destroy(ADS_STRUCT **ads) SAFE_FREE((*ads)->schema.sfu_gidnumber_attr); SAFE_FREE((*ads)->schema.sfu_shell_attr); SAFE_FREE((*ads)->schema.sfu_homedir_attr); + SAFE_FREE((*ads)->schema.sfu_gecos_attr); ZERO_STRUCTP(*ads); diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 6d2155fae0..cb7dbc575b 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2628,7 +2628,7 @@ BOOL ads_check_sfu_mapping(ADS_STRUCT *ads) { BOOL ret = False; TALLOC_CTX *ctx = NULL; - const char *gidnumber, *uidnumber, *homedir, *shell; + const char *gidnumber, *uidnumber, *homedir, *shell, *gecos; ctx = talloc_init("ads_check_sfu_mapping"); if (ctx == NULL) @@ -2654,6 +2654,11 @@ BOOL ads_check_sfu_mapping(ADS_STRUCT *ads) goto done; ads->schema.sfu_shell_attr = SMB_STRDUP(shell); + gecos = ads_get_attrname_by_oid(ads, ctx, ADS_ATTR_SFU_GECOS_OID); + if (gecos == NULL) + goto done; + ads->schema.sfu_gecos_attr = SMB_STRDUP(gecos); + ret = True; done: if (ctx) -- cgit From e54786b53543b4667288c64abb55478fddd95061 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 27 Feb 2006 10:32:45 +0000 Subject: r13711: * Correctly handle acb_info/acct_flags as uint32 not as uint16. * Fix a couple of related parsing issues. * in the info3 reply in a samlogon, return the ACB-flags (instead of returning zero) Guenther (This used to be commit 5b89e8bc24f0fdc8b52d5c9e849aba723df34ea7) --- source3/libads/ads_utils.c | 42 ++++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_utils.c b/source3/libads/ads_utils.c index 1aad0bed54..0cbf235989 100644 --- a/source3/libads/ads_utils.c +++ b/source3/libads/ads_utils.c @@ -25,21 +25,28 @@ /* translated the ACB_CTRL Flags to UserFlags (userAccountControl) */ -uint32 ads_acb2uf(uint16 acb) +uint32 ads_acb2uf(uint32 acb) { uint32 uf = 0x00000000; - if (acb & ACB_DISABLED) uf |= UF_ACCOUNTDISABLE; - if (acb & ACB_HOMDIRREQ) uf |= UF_HOMEDIR_REQUIRED; - if (acb & ACB_PWNOTREQ) uf |= UF_PASSWD_NOTREQD; - if (acb & ACB_TEMPDUP) uf |= UF_TEMP_DUPLICATE_ACCOUNT; - if (acb & ACB_NORMAL) uf |= UF_NORMAL_ACCOUNT; - if (acb & ACB_MNS) uf |= UF_MNS_LOGON_ACCOUNT; - if (acb & ACB_DOMTRUST) uf |= UF_INTERDOMAIN_TRUST_ACCOUNT; - if (acb & ACB_WSTRUST) uf |= UF_WORKSTATION_TRUST_ACCOUNT; - if (acb & ACB_SVRTRUST) uf |= UF_SERVER_TRUST_ACCOUNT; - if (acb & ACB_PWNOEXP) uf |= UF_DONT_EXPIRE_PASSWD; - if (acb & ACB_AUTOLOCK) uf |= UF_LOCKOUT; + if (acb & ACB_DISABLED) uf |= UF_ACCOUNTDISABLE; + if (acb & ACB_HOMDIRREQ) uf |= UF_HOMEDIR_REQUIRED; + if (acb & ACB_PWNOTREQ) uf |= UF_PASSWD_NOTREQD; + if (acb & ACB_TEMPDUP) uf |= UF_TEMP_DUPLICATE_ACCOUNT; + if (acb & ACB_NORMAL) uf |= UF_NORMAL_ACCOUNT; + if (acb & ACB_MNS) uf |= UF_MNS_LOGON_ACCOUNT; + if (acb & ACB_DOMTRUST) uf |= UF_INTERDOMAIN_TRUST_ACCOUNT; + if (acb & ACB_WSTRUST) uf |= UF_WORKSTATION_TRUST_ACCOUNT; + if (acb & ACB_SVRTRUST) uf |= UF_SERVER_TRUST_ACCOUNT; + if (acb & ACB_PWNOEXP) uf |= UF_DONT_EXPIRE_PASSWD; + if (acb & ACB_AUTOLOCK) uf |= UF_LOCKOUT; + if (acb & ACB_USE_DES_KEY_ONLY) uf |= UF_USE_DES_KEY_ONLY; + if (acb & ACB_SMARTCARD_REQUIRED) uf |= UF_SMARTCARD_REQUIRED; + if (acb & ACB_TRUSTED_FOR_DELEGATION) uf |= UF_TRUSTED_FOR_DELEGATION; + if (acb & ACB_DONT_REQUIRE_PREAUTH) uf |= UF_DONT_REQUIRE_PREAUTH; + if (acb & ACB_NO_AUTH_DATA_REQD) uf |= UF_NO_AUTH_DATA_REQUIRED; + if (acb & ACB_NOT_DELEGATED) uf |= UF_NOT_DELEGATED; + if (acb & ACB_ENC_TXT_PWD_ALLOWED) uf |= UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED; return uf; } @@ -47,9 +54,9 @@ uint32 ads_acb2uf(uint16 acb) /* translated the UserFlags (userAccountControl) to ACB_CTRL Flags */ -uint16 ads_uf2acb(uint32 uf) +uint32 ads_uf2acb(uint32 uf) { - uint16 acb = 0x0000; + uint32 acb = 0x00000000; if (uf & UF_ACCOUNTDISABLE) acb |= ACB_DISABLED; if (uf & UF_HOMEDIR_REQUIRED) acb |= ACB_HOMDIRREQ; @@ -57,6 +64,13 @@ uint16 ads_uf2acb(uint32 uf) if (uf & UF_MNS_LOGON_ACCOUNT) acb |= ACB_MNS; if (uf & UF_DONT_EXPIRE_PASSWD) acb |= ACB_PWNOEXP; if (uf & UF_LOCKOUT) acb |= ACB_AUTOLOCK; + if (uf & UF_USE_DES_KEY_ONLY) acb |= ACB_USE_DES_KEY_ONLY; + if (uf & UF_SMARTCARD_REQUIRED) acb |= ACB_SMARTCARD_REQUIRED; + if (uf & UF_TRUSTED_FOR_DELEGATION) acb |= ACB_TRUSTED_FOR_DELEGATION; + if (uf & UF_DONT_REQUIRE_PREAUTH) acb |= ACB_DONT_REQUIRE_PREAUTH; + if (uf & UF_NO_AUTH_DATA_REQUIRED) acb |= ACB_NO_AUTH_DATA_REQD; + if (uf & UF_NOT_DELEGATED) acb |= ACB_NOT_DELEGATED; + if (uf & UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED) acb |= ACB_ENC_TXT_PWD_ALLOWED; switch (uf & UF_ACCOUNT_TYPE_MASK) { -- cgit From dbb4840da528ed6931ffa1c70885b3645dff25a3 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 7 Mar 2006 16:01:57 +0000 Subject: r13950: Fix Coverity bug #168 (This used to be commit cbf894c0e37964df57bd6a91ac10dfff571b1b3c) --- source3/libads/ads_ldap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libads') diff --git a/source3/libads/ads_ldap.c b/source3/libads/ads_ldap.c index fea4cd0fd0..841bee6a1e 100644 --- a/source3/libads/ads_ldap.c +++ b/source3/libads/ads_ldap.c @@ -84,6 +84,7 @@ ADS_STATUS ads_sid_to_dn(ADS_STRUCT *ads, if (!*dn) { ads_memfree(ads, dn2); + dn2 = NULL; rc = ADS_ERROR_NT(NT_STATUS_NO_MEMORY); goto done; } -- cgit From c2288e6db34207948413411764175990f563168e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 7 Mar 2006 16:06:26 +0000 Subject: r13951: Fix Coverity Bug #163. This code was not used anyway :-) Volker (This used to be commit bbfb20569380529d60e3c61cd0be63a09eecfd17) --- source3/libads/ldap.c | 28 ---------------------------- 1 file changed, 28 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index cb7dbc575b..26b86f64d1 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -823,34 +823,6 @@ char *ads_get_dn_canonical(ADS_STRUCT *ads, void *msg) #endif } - -/** - * Get the parent dn from a search result - * @param ads connection to ads server - * @param msg Search result - * @return parent dn string - **/ -char *ads_get_parent_dn(ADS_STRUCT *ads, void *msg) -{ - char *mydn, *p, *dn; - - dn = ads_get_dn(ads, msg); - if (dn == NULL) { - return NULL; - } - - mydn = dn; - ads_memfree(ads, dn); - - p = strchr(mydn, ','); - - if (p == NULL) { - return NULL; - } - - return p+1; -} - /** * Get the parent from a dn * @param dn the dn to return the parent from -- cgit From 3432273ab0f647e60960152514c1df87093614af Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 7 Mar 2006 16:56:31 +0000 Subject: r13965: Make sure we always reset the userAccountControl bits when re-joining with an existing account. Guenther (This used to be commit e4c12ab167ee83772a2bdd1946b8d73613fc0d7e) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 26b86f64d1..babbabdd80 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1526,9 +1526,9 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *machine_name if (!exists) { ads_mod_str(ctx, &mods, "cn", machine_name); ads_mod_str(ctx, &mods, "sAMAccountName", samAccountName); - ads_mod_str(ctx, &mods, "userAccountControl", controlstr); ads_mod_strlist(ctx, &mods, "objectClass", objectClass); } + ads_mod_str(ctx, &mods, "userAccountControl", controlstr); ads_mod_str(ctx, &mods, "dNSHostName", my_fqdn); ads_mod_str(ctx, &mods, "userPrincipalName", host_upn); ads_mod_strlist(ctx, &mods, "servicePrincipalName", servicePrincipalName); -- cgit From c7c3b98d4b7b28ffcfa6ab26128f769555d5c03a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 8 Mar 2006 06:32:21 +0000 Subject: r14017: Okay, okay, I have turned a double-free into dead code :-) Fix Coverity # 214. Volker (This used to be commit 4a75edf9deca2be18670d7f9f2e383ed0898512c) --- source3/libads/ads_ldap.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_ldap.c b/source3/libads/ads_ldap.c index 841bee6a1e..42821496c3 100644 --- a/source3/libads/ads_ldap.c +++ b/source3/libads/ads_ldap.c @@ -83,8 +83,6 @@ ADS_STATUS ads_sid_to_dn(ADS_STRUCT *ads, *dn = talloc_strdup(mem_ctx, dn2); if (!*dn) { - ads_memfree(ads, dn2); - dn2 = NULL; rc = ADS_ERROR_NT(NT_STATUS_NO_MEMORY); goto done; } -- cgit From e11a85eebd660073f3f68b7d6d289476e5193d28 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 9 Mar 2006 14:51:40 +0000 Subject: r14074: Some cleanup; there is no point in declaring and mapping KRB5KRB_ERR_RESPONSE_TOO_BIG when the krb5 library does not know about this. Guenther (This used to be commit 4a1a3c4808307e09fa8ff85da9a963a4a6f0e9ae) --- source3/libads/krb5_errs.c | 35 ++++++----------------------------- 1 file changed, 6 insertions(+), 29 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/krb5_errs.c b/source3/libads/krb5_errs.c index 0277596436..0c2e704702 100644 --- a/source3/libads/krb5_errs.c +++ b/source3/libads/krb5_errs.c @@ -23,7 +23,7 @@ #ifdef HAVE_KRB5 static const struct { - long krb5_code; + krb5_error_code krb5_code; NTSTATUS ntstatus; } krb5_to_nt_status_map[] = { {KRB5_CC_IO, NT_STATUS_UNEXPECTED_IO_ERROR}, @@ -52,13 +52,15 @@ static const struct { {KRB5KRB_AP_ERR_SKEW, NT_STATUS_TIME_DIFFERENCE_AT_DC}, {KRB5KRB_AP_ERR_TKT_EXPIRED, NT_STATUS_LOGON_FAILURE}, {KRB5KRB_ERR_GENERIC, NT_STATUS_UNSUCCESSFUL}, +#if defined(KRB5KRB_ERR_RESPONSE_TOO_BIG) {KRB5KRB_ERR_RESPONSE_TOO_BIG, NT_STATUS_PROTOCOL_UNREACHABLE}, +#endif {0, NT_STATUS_OK} }; static const struct { NTSTATUS ntstatus; - long krb5_code; + krb5_error_code krb5_code; } nt_status_to_krb5_map[] = { {NT_STATUS_LOGON_FAILURE, KRB5KDC_ERR_PREAUTH_FAILED}, {NT_STATUS_NO_LOGON_SERVERS, KRB5_KDC_UNREACH}, @@ -68,7 +70,7 @@ static const struct { /***************************************************************************** convert a KRB5 error to a NT status32 code *****************************************************************************/ -NTSTATUS krb5_to_nt_status(int kerberos_error) + NTSTATUS krb5_to_nt_status(krb5_error_code kerberos_error) { int i; @@ -87,7 +89,7 @@ NTSTATUS krb5_to_nt_status(int kerberos_error) /***************************************************************************** convert an NT status32 code to a KRB5 error *****************************************************************************/ -int nt_status_to_krb5(NTSTATUS nt_status) + krb5_error_code nt_status_to_krb5(NTSTATUS nt_status) { int i; @@ -103,30 +105,5 @@ int nt_status_to_krb5(NTSTATUS nt_status) return KRB5KRB_ERR_GENERIC; } -#else - -/***************************************************************************** -convert a KRB5 error to a NT status32 code - *****************************************************************************/ -NTSTATUS krb5_to_nt_status(int kerberos_error) -{ - if (kerberos_error == 0) { - return NT_STATUS_OK; - } - - return NT_STATUS_UNSUCCESSFUL; -} - -/***************************************************************************** -convert an NT status32 code to a KRB5 error - *****************************************************************************/ -int nt_status_to_krb5(NTSTATUS nt_status) -{ - if (NT_STATUS_EQUAL(nt_status, NT_STATUS_OK)) { - return 0; - } - return -1; /* FIXME: what to return here ? */ -} - #endif -- cgit From acf0c6fb66b4182a0e5e7610d5063649ca237311 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 9 Mar 2006 22:49:38 +0000 Subject: r14118: Fix coverity bug #24. Missing return statement meant a possible NULL ptr deref. Jeremy. (This used to be commit 78ac3f9cbdabc1df9480f75fb3910a3a108a0e91) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index babbabdd80..dd49c706f4 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2692,7 +2692,7 @@ ADS_STATUS ads_workgroup_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char * asprintf(&expr, "(&(objectclass=computer)(dnshostname=%s.%s))", ads->config.ldap_server_name, ads->config.realm); if (expr == NULL) { - ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); } rc = ads_search(ads, &res, expr, attrs); -- cgit From 5f224c2c265faa50e5495cc738f1a62c6aa70d56 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 10 Mar 2006 18:32:18 +0000 Subject: r14170: Paranioa fix for sesssetup. Fix Coverity bug #26. Guard against NULL ref. Jeremy. (This used to be commit c0f906ac8de850f4566b6b3be4e3c7d245e6e252) --- source3/libads/krb5_setpw.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 6ffd218e96..42ca36f344 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -65,19 +65,22 @@ static DATA_BLOB encode_krb5_setpw(const char *principal, const char *password) princ = SMB_STRDUP(principal); if ((c = strchr_m(princ, '/')) == NULL) { - c = princ; + c = princ; } else { - *c = '\0'; - c++; - princ_part1 = princ; + *c = '\0'; + c++; + princ_part1 = princ; } princ_part2 = c; if ((c = strchr_m(c, '@')) != NULL) { - *c = '\0'; - c++; - realm = c; + *c = '\0'; + c++; + realm = c; + } else { + /* We must have a realm component. */ + return data_blob(NULL, 0); } memset(&req, 0, sizeof(req)); @@ -97,8 +100,9 @@ static DATA_BLOB encode_krb5_setpw(const char *principal, const char *password) asn1_push_tag(&req, ASN1_CONTEXT(1)); asn1_push_tag(&req, ASN1_SEQUENCE(0)); - if (princ_part1) - asn1_write_GeneralString(&req, princ_part1); + if (princ_part1) { + asn1_write_GeneralString(&req, princ_part1); + } asn1_write_GeneralString(&req, princ_part2); asn1_pop_tag(&req); @@ -151,6 +155,10 @@ static krb5_error_code build_kpasswd_request(uint16 pversion, else return EINVAL; + if (setpw.data == NULL || setpw.length == 0) { + return EINVAL; + } + encoded_setpw.data = (char *)setpw.data; encoded_setpw.length = setpw.length; -- cgit From 06f7ee5d4b9d2f94c0178a0c979f50fa2f96b905 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Sun, 12 Mar 2006 19:56:10 +0000 Subject: r14252: Fix Coverity #72: free alloc'ed storage before return. Also found one more that coverity didn't find from asprintf. (This used to be commit 37b6e2c8de41754a5a1a3a6f798d57aa5d533ada) --- source3/libads/ldap.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index dd49c706f4..e1cea533a0 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1914,7 +1914,10 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) * we have to bail out before prs_init */ ps_wire.is_dynamic = False; - if (!ads) return ADS_ERROR(LDAP_SERVER_DOWN); + if (!ads) { + SAFE_FREE(escaped_hostname); + return ADS_ERROR(LDAP_SERVER_DOWN); + } ret = ADS_ERROR(LDAP_SUCCESS); @@ -1932,6 +1935,8 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) ret = ads_search(ads, (void *) &res, expr, attrs); + SAFE_FREE(expr); + if (!ADS_ERR_OK(ret)) return ret; if ( !(msg = ads_first_entry(ads, res) )) { -- cgit From 9fb55b5cb8e916505d3b823c6761c2eff8a5f6ed Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 17 Mar 2006 09:25:26 +0000 Subject: r14503: Fix principal in debug statement. Guenther (This used to be commit 7b1fcb75dadd5ff232d60f93206867cf13322f2e) --- source3/libads/kerberos.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 67f8433775..c82310dd08 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -372,9 +372,8 @@ static krb5_error_code get_service_ticket(krb5_context ctx, } if ((err = kerberos_kinit_password(machine_account, password, 0, NULL, NULL, LIBADS_CCACHE_NAME, False, 0)) != 0) { - DEBUG(0,("get_service_ticket: kerberos_kinit_password %s@%s failed: %s\n", + DEBUG(0,("get_service_ticket: kerberos_kinit_password %s failed: %s\n", machine_account, - lp_realm(), error_message(err))); goto out; } -- cgit From 0342db7e87f4c98da4051e9fc7a8abf1e36218d0 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 17 Mar 2006 13:57:00 +0000 Subject: r14512: Guenther, This code breaks winbind with MIT krb1.3. I'm disabling it for now until we have en effective means of dealing with the ticket request flags for users and computers. (This used to be commit 635f0c9c01c2e389ca916e9004e9ea064bf69cbb) --- source3/libads/kerberos.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index c82310dd08..17e350d754 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -72,7 +72,9 @@ int kerberos_kinit_password(const char *principal, krb5_ccache cc = NULL; krb5_principal me; krb5_creds my_creds; +#if 0 krb5_get_init_creds_opt opt; +#endif initialize_krb5_error_table(); if ((code = krb5_init_context(&ctx))) @@ -95,9 +97,12 @@ int kerberos_kinit_password(const char *principal, return code; } +#if 0 /* This code causes problems with MIT krb5 1.3 when asking for a + TGT for the machine account */ krb5_get_init_creds_opt_init(&opt); krb5_get_init_creds_opt_set_renew_life(&opt, renewable_time); krb5_get_init_creds_opt_set_forwardable(&opt, 1); +#endif if (request_pac) { #ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PAC_REQUEST @@ -105,9 +110,14 @@ int kerberos_kinit_password(const char *principal, #endif } +#if 0 if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, CONST_DISCARD(char *,password), - kerb_prompter, - NULL, 0, NULL, &opt))) { + kerb_prompter, NULL, 0, NULL, &opt))) +#else + if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, CONST_DISCARD(char *,password), + kerb_prompter, NULL, 0, NULL, NULL))) +#endif + { krb5_free_principal(ctx, me); krb5_free_context(ctx); return code; -- cgit From 492af5e91857fa27f68758354a3e35afcc84c238 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 20 Mar 2006 10:05:51 +0000 Subject: r14576: Skip remaining keytab entries when we have a clear indication that krb5_rd_req could decrypt the ticket but that ticket is just not valid at the moment (either not yet valid or already expired). (This also prevents an MIT kerberos related crash) Guenther (This used to be commit 8a0c1933d3f354a8aff67482b8c7d0d1083e0c8f) --- source3/libads/kerberos_verify.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 220bf14e32..83bdb3f862 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -111,6 +111,22 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut DEBUG(10,("ads_keytab_verify_ticket: " "krb5_rd_req_return_keyblock_from_keytab(%s) failed: %s\n", entry_princ_s, error_message(ret))); + + /* workaround for MIT: + * as krb5_ktfile_get_entry will + * explicitly close the + * krb5_keytab as soon as + * krb5_rd_req has sucessfully + * decrypted the ticket but the + * ticket is not valid yet (due + * to clockskew) there is no + * point in querying more + * keytab entries - Guenther */ + + if (ret == KRB5KRB_AP_ERR_TKT_NYV || + ret == KRB5KRB_AP_ERR_TKT_EXPIRED) { + break; + } } else { DEBUG(3,("ads_keytab_verify_ticket: " "krb5_rd_req_return_keyblock_from_keytab succeeded for principal %s\n", @@ -243,11 +259,17 @@ static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context au krb5_free_keyblock(context, key); break; } - + DEBUG((ret != KRB5_BAD_ENCTYPE) ? 3 : 10, ("ads_secrets_verify_ticket: enc type [%u] failed to decrypt with error %s\n", (unsigned int)enctypes[i], error_message(ret))); + /* successfully decrypted but ticket is just not valid at the moment */ + if (ret == KRB5KRB_AP_ERR_TKT_NYV || + ret == KRB5KRB_AP_ERR_TKT_EXPIRED) { + break; + } + krb5_free_keyblock(context, key); } -- cgit From 485a286a65d3b37f424f5701179f73c99eb9b5b9 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 20 Mar 2006 19:05:44 +0000 Subject: r14585: Tighten argument list of kerberos_kinit_password again, kerberos_kinit_password_ext provides access to more options. Guenther (This used to be commit afc519530f94b420b305fc28f83c16db671d0d7f) --- source3/libads/kerberos.c | 24 ++++++++++++++++++++---- source3/libads/krb5_setpw.c | 2 +- 2 files changed, 21 insertions(+), 5 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 17e350d754..029e42c0c2 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -58,7 +58,7 @@ kerb_prompter(krb5_context ctx, void *data, place in default cache location. remus@snapserver.com */ -int kerberos_kinit_password(const char *principal, +int kerberos_kinit_password_ext(const char *principal, const char *password, int time_offset, time_t *expire_time, @@ -187,7 +187,7 @@ int ads_kinit_password(ADS_STRUCT *ads) return KRB5_LIBOS_CANTREADPWD; } - ret = kerberos_kinit_password(s, ads->auth.password, ads->auth.time_offset, + ret = kerberos_kinit_password_ext(s, ads->auth.password, ads->auth.time_offset, &ads->auth.expire, NULL, NULL, False, ads->auth.renewable); if (ret) { @@ -380,8 +380,8 @@ static krb5_error_code get_service_ticket(krb5_context ctx, if (password == NULL) { goto out; } - if ((err = kerberos_kinit_password(machine_account, password, 0, NULL, NULL, - LIBADS_CCACHE_NAME, False, 0)) != 0) { + if ((err = kerberos_kinit_password(machine_account, password, + 0, LIBADS_CCACHE_NAME)) != 0) { DEBUG(0,("get_service_ticket: kerberos_kinit_password %s failed: %s\n", machine_account, error_message(err))); @@ -811,4 +811,20 @@ BOOL kerberos_derive_cifs_salting_principals(void) } return retval; } + +int kerberos_kinit_password(const char *principal, + const char *password, + int time_offset, + const char *cache_name) +{ + return kerberos_kinit_password_ext(principal, + password, + time_offset, + 0, + 0, + cache_name, + False, + 0); +} + #endif diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 42ca36f344..415c1e9229 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -685,7 +685,7 @@ ADS_STATUS kerberos_set_password(const char *kpasswd_server, { int ret; - if ((ret = kerberos_kinit_password(auth_principal, auth_password, time_offset, NULL, NULL, NULL, False, 0))) { + if ((ret = kerberos_kinit_password(auth_principal, auth_password, time_offset, NULL))) { DEBUG(1,("Failed kinit for principal %s (%s)\n", auth_principal, error_message(ret))); return ADS_ERROR_KRB5(ret); } -- cgit From e4dc7454346da21d5bc7df7028057d47d7d4d0a5 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 21 Mar 2006 11:14:29 +0000 Subject: r14611: Fix init_creds_opts issue jerry discovered when using MIT krb5 1.3: We were using a far too short renewable_time in the request; newer MIT releases take care interally that the renewable time is never shorter then the default ticket lifetime. Guenther (This used to be commit bde4a4018e26bc9aab4b928ec9811c05b21574f3) --- source3/libads/kerberos.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 029e42c0c2..e5211813d3 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -72,9 +72,7 @@ int kerberos_kinit_password_ext(const char *principal, krb5_ccache cc = NULL; krb5_principal me; krb5_creds my_creds; -#if 0 krb5_get_init_creds_opt opt; -#endif initialize_krb5_error_table(); if ((code = krb5_init_context(&ctx))) @@ -97,12 +95,9 @@ int kerberos_kinit_password_ext(const char *principal, return code; } -#if 0 /* This code causes problems with MIT krb5 1.3 when asking for a - TGT for the machine account */ krb5_get_init_creds_opt_init(&opt); krb5_get_init_creds_opt_set_renew_life(&opt, renewable_time); krb5_get_init_creds_opt_set_forwardable(&opt, 1); -#endif if (request_pac) { #ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PAC_REQUEST @@ -110,13 +105,8 @@ int kerberos_kinit_password_ext(const char *principal, #endif } -#if 0 if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, CONST_DISCARD(char *,password), kerb_prompter, NULL, 0, NULL, &opt))) -#else - if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, CONST_DISCARD(char *,password), - kerb_prompter, NULL, 0, NULL, NULL))) -#endif { krb5_free_principal(ctx, me); krb5_free_context(ctx); -- cgit From d7174c1a5171fca5c0b4436f3f1e11cbf39f245c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 23 Mar 2006 17:32:21 +0000 Subject: r14682: Small cleanup in ads_verify_ticket. Guenther (This used to be commit 90df68634b508b0a58f0a15ab62e9cead85765b6) --- source3/libads/kerberos_verify.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 83bdb3f862..934c1131eb 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -399,10 +399,10 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, DEBUG(3,("ads_verify_ticket: krb5_rd_req with auth failed (%s)\n", error_message(ret))); goto out; - } else { - authtime = get_authtime_from_tkt(tkt); - client_principal = get_principal_from_tkt(tkt); - } + } + + authtime = get_authtime_from_tkt(tkt); + client_principal = get_principal_from_tkt(tkt); ret = krb5_mk_rep(context, auth_context, &packet); if (ret) { @@ -459,8 +459,7 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, #endif #endif - if ((ret = krb5_unparse_name(context, get_principal_from_tkt(tkt), - principal))) { + if ((ret = krb5_unparse_name(context, client_principal, principal))) { DEBUG(3,("ads_verify_ticket: krb5_unparse_name failed (%s)\n", error_message(ret))); sret = NT_STATUS_LOGON_FAILURE; -- cgit From 92f139d4c4c7a07dd199b09b24bfc162eb1ab6bf Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Thu, 6 Apr 2006 01:46:01 +0000 Subject: r14931: Fix #1374: can't join an OU with name that contains '#' I had to eliminate "\" as an OU path separator, because it is the escape char in LDAP. We still accept "/", but using the escape char is just not a good choice. (This used to be commit 1953f63903e64e0a33eb981c51b8ca4beb673af2) --- source3/libads/ldap.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index e1cea533a0..c2ebf14d2f 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1083,7 +1083,8 @@ ADS_STATUS ads_del_dn(ADS_STRUCT *ads, char *del_dn) /** * Build an org unit string * if org unit is Computers or blank then assume a container, otherwise - * assume a \ separated list of organisational units + * assume a / separated list of organisational units. + * jmcd: '\' is now used for escapes so certain chars can be in the ou (e.g. #) * @param ads connection to ads server * @param org_unit Organizational unit * @return org unit string - caller must free @@ -1104,7 +1105,10 @@ char *ads_ou_string(ADS_STRUCT *ads, const char *org_unit) return SMB_STRDUP("cn=Computers"); } - return ads_build_path(org_unit, "\\/", "ou=", 1); + /* jmcd: removed "\\" from the separation chars, because it is + needed as an escape for chars like '#' which are valid in an + OU name */ + return ads_build_path(org_unit, "/", "ou=", 1); } /** -- cgit From b68b05854ff5a7e75953462eba74f97753428ef1 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 24 Apr 2006 15:57:54 +0000 Subject: r15210: Add wrapper functions smb_krb5_parse_name, smb_krb5_unparse_name, smb_krb5_parse_name_norealm_conv that pull/push from unix charset to utf8 (which krb5 uses on the wire). This should fix issues when the unix charset is not compatible with or set to utf8. Jeremy. (This used to be commit 37ab42afbc9a79cf5b04ce6a1bf4060e9c961199) --- source3/libads/kerberos.c | 28 +++++++++++++--------------- source3/libads/kerberos_keytab.c | 22 +++++++++++----------- source3/libads/kerberos_verify.c | 20 +++++++++----------- source3/libads/krb5_setpw.c | 6 +++--- source3/libads/sasl.c | 2 +- 5 files changed, 37 insertions(+), 41 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index e5211813d3..960709a5f0 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -90,7 +90,7 @@ int kerberos_kinit_password_ext(const char *principal, return code; } - if ((code = krb5_parse_name(ctx, principal, &me))) { + if ((code = smb_krb5_parse_name(ctx, principal, &me))) { krb5_free_context(ctx); return code; } @@ -260,21 +260,21 @@ krb5_principal kerberos_fetch_salt_princ_for_host_princ(krb5_context context, char *unparsed_name = NULL, *salt_princ_s = NULL; krb5_principal ret_princ = NULL; - if (krb5_unparse_name(context, host_princ, &unparsed_name) != 0) { + if (smb_krb5_unparse_name(context, host_princ, &unparsed_name) != 0) { return (krb5_principal)NULL; } if ((salt_princ_s = kerberos_secrets_fetch_salting_principal(unparsed_name, enctype)) == NULL) { - krb5_free_unparsed_name(context, unparsed_name); + SAFE_FREE(unparsed_name); return (krb5_principal)NULL; } - if (krb5_parse_name(context, salt_princ_s, &ret_princ) != 0) { - krb5_free_unparsed_name(context, unparsed_name); + if (smb_krb5_parse_name(context, salt_princ_s, &ret_princ) != 0) { + SAFE_FREE(unparsed_name); SAFE_FREE(salt_princ_s); return (krb5_principal)NULL; } - krb5_free_unparsed_name(context, unparsed_name); + SAFE_FREE(unparsed_name); SAFE_FREE(salt_princ_s); return ret_princ; } @@ -308,11 +308,11 @@ BOOL kerberos_secrets_store_salting_principal(const char *service, asprintf(&princ_s, "%s@%s", service, lp_realm()); } - if (krb5_parse_name(context, princ_s, &princ) != 0) { + if (smb_krb5_parse_name(context, princ_s, &princ) != 0) { goto out; } - if (krb5_unparse_name(context, princ, &unparsed_name) != 0) { + if (smb_krb5_unparse_name(context, princ, &unparsed_name) != 0) { goto out; } @@ -331,10 +331,8 @@ BOOL kerberos_secrets_store_salting_principal(const char *service, SAFE_FREE(key); SAFE_FREE(princ_s); + SAFE_FREE(unparsed_name); - if (unparsed_name) { - krb5_free_unparsed_name(context, unparsed_name); - } if (context) { krb5_free_context(context); } @@ -396,8 +394,8 @@ static krb5_error_code get_service_ticket(krb5_context ctx, asprintf(&service_s, "%s@%s", service_principal, lp_realm()); } - if ((err = krb5_parse_name(ctx, service_s, &creds.server))) { - DEBUG(0,("get_service_ticket: krb5_parse_name %s failed: %s\n", + if ((err = smb_krb5_parse_name(ctx, service_s, &creds.server))) { + DEBUG(0,("get_service_ticket: smb_krb5_parse_name %s failed: %s\n", service_s, error_message(err))); goto out; } @@ -476,8 +474,8 @@ static BOOL verify_service_password(krb5_context ctx, asprintf(&salting_s, "%s@%s", salting_principal, lp_realm()); } - if ((err = krb5_parse_name(ctx, salting_s, &salting_kprinc))) { - DEBUG(0,("verify_service_password: krb5_parse_name %s failed: %s\n", + if ((err = smb_krb5_parse_name(ctx, salting_s, &salting_kprinc))) { + DEBUG(0,("verify_service_password: smb_krb5_parse_name %s failed: %s\n", salting_s, error_message(err))); goto out; } diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c index f6ed107ee0..fc87b687d1 100644 --- a/source3/libads/kerberos_keytab.c +++ b/source3/libads/kerberos_keytab.c @@ -130,9 +130,9 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc) /* Guess at how the KDC is salting keys for this principal. */ kerberos_derive_salting_principal(princ_s); - ret = krb5_parse_name(context, princ_s, &princ); + ret = smb_krb5_parse_name(context, princ_s, &princ); if (ret) { - DEBUG(1,("ads_keytab_add_entry: krb5_parse_name(%s) failed (%s)\n", princ_s, error_message(ret))); + DEBUG(1,("ads_keytab_add_entry: smb_krb5_parse_name(%s) failed (%s)\n", princ_s, error_message(ret))); goto out; } @@ -150,9 +150,10 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc) while(!krb5_kt_next_entry(context, keytab, &kt_entry, &cursor)) { BOOL compare_name_ok = False; - ret = krb5_unparse_name(context, kt_entry.principal, &ktprinc); + ret = smb_krb5_unparse_name(context, kt_entry.principal, &ktprinc); if (ret) { - DEBUG(1,("ads_keytab_add_entry: krb5_unparse_name failed (%s)\n", error_message(ret))); + DEBUG(1,("ads_keytab_add_entry: smb_krb5_unparse_name failed (%s)\n", + error_message(ret))); goto out; } @@ -176,8 +177,7 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc) ktprinc, kt_entry.vno)); } - krb5_free_unparsed_name(context, ktprinc); - ktprinc = NULL; + SAFE_FREE(ktprinc); if (compare_name_ok) { if (kt_entry.vno == kvno - 1) { @@ -581,9 +581,9 @@ int ads_keytab_create_default(ADS_STRUCT *ads) char *p; /* This returns a malloc'ed string in ktprinc. */ - ret = krb5_unparse_name(context, kt_entry.principal, &ktprinc); + ret = smb_krb5_unparse_name(context, kt_entry.principal, &ktprinc); if (ret) { - DEBUG(1,("krb5_unparse_name failed (%s)\n", error_message(ret))); + DEBUG(1,("smb_krb5_unparse_name failed (%s)\n", error_message(ret))); goto done; } /* @@ -606,12 +606,12 @@ int ads_keytab_create_default(ADS_STRUCT *ads) break; } if (!strcmp(oldEntries[i], ktprinc)) { - krb5_free_unparsed_name(context, ktprinc); + SAFE_FREE(ktprinc); break; } } if (i == found) { - krb5_free_unparsed_name(context, ktprinc); + SAFE_FREE(ktprinc); } } smb_krb5_kt_free_entry(context, &kt_entry); @@ -620,7 +620,7 @@ int ads_keytab_create_default(ADS_STRUCT *ads) ret = 0; for (i = 0; oldEntries[i]; i++) { ret |= ads_keytab_add_entry(ads, oldEntries[i]); - krb5_free_unparsed_name(context, oldEntries[i]); + SAFE_FREE(oldEntries[i]); } krb5_kt_end_seq_get(context, keytab, &cursor); } diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 934c1131eb..fa957aa9c0 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -90,9 +90,10 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut if (ret != KRB5_KT_END && ret != ENOENT ) { while (!auth_ok && (krb5_kt_next_entry(context, keytab, &kt_entry, &kt_cursor) == 0)) { - ret = krb5_unparse_name(context, kt_entry.principal, &entry_princ_s); + ret = smb_krb5_unparse_name(context, kt_entry.principal, &entry_princ_s); if (ret) { - DEBUG(1, ("ads_keytab_verify_ticket: krb5_unparse_name failed (%s)\n", error_message(ret))); + DEBUG(1, ("ads_keytab_verify_ticket: smb_krb5_unparse_name failed (%s)\n", + error_message(ret))); goto out; } @@ -138,8 +139,7 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut } /* Free the name we parsed. */ - krb5_free_unparsed_name(context, entry_princ_s); - entry_princ_s = NULL; + SAFE_FREE(entry_princ_s); /* Free the entry we just read. */ smb_krb5_kt_free_entry(context, &kt_entry); @@ -165,9 +165,7 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut } } - if (entry_princ_s) { - krb5_free_unparsed_name(context, entry_princ_s); - } + SAFE_FREE(entry_princ_s); { krb5_keytab_entry zero_kt_entry; @@ -343,9 +341,9 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, asprintf(&host_princ_s, "%s$", global_myname()); strlower_m(host_princ_s); - ret = krb5_parse_name(context, host_princ_s, &host_princ); + ret = smb_krb5_parse_name(context, host_princ_s, &host_princ); if (ret) { - DEBUG(1,("ads_verify_ticket: krb5_parse_name(%s) failed (%s)\n", + DEBUG(1,("ads_verify_ticket: smb_krb5_parse_name(%s) failed (%s)\n", host_princ_s, error_message(ret))); goto out; } @@ -459,8 +457,8 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, #endif #endif - if ((ret = krb5_unparse_name(context, client_principal, principal))) { - DEBUG(3,("ads_verify_ticket: krb5_unparse_name failed (%s)\n", + if ((ret = smb_krb5_unparse_name(context, client_principal, principal))) { + DEBUG(3,("ads_verify_ticket: smb_krb5_unparse_name failed (%s)\n", error_message(ret))); sret = NT_STATUS_LOGON_FAILURE; goto out; diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 415c1e9229..254ca7b2a3 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -521,7 +521,7 @@ ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ, realm++; asprintf(&princ_name, "kadmin/changepw@%s", realm); - ret = krb5_parse_name(context, princ_name, &creds.server); + ret = smb_krb5_parse_name(context, princ_name, &creds.server); if (ret) { krb5_cc_close(context, ccache); krb5_free_context(context); @@ -531,7 +531,7 @@ ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ, free(princ_name); /* parse the principal we got as a function argument */ - ret = krb5_parse_name(context, princ, &principal); + ret = smb_krb5_parse_name(context, princ, &principal); if (ret) { krb5_cc_close(context, ccache); krb5_free_principal(context, creds.server); @@ -633,7 +633,7 @@ static ADS_STATUS ads_krb5_chg_password(const char *kdc_host, return ADS_ERROR_KRB5(ret); } - if ((ret = krb5_parse_name(context, principal, + if ((ret = smb_krb5_parse_name(context, principal, &princ))) { krb5_free_context(context); DEBUG(1,("Failed to parse %s (%s)\n", principal, error_message(ret))); diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index d8d33a924f..a12af43eb3 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -304,7 +304,7 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) if (!ADS_ERR_OK(status)) { return status; } - status = ADS_ERROR_KRB5(krb5_parse_name(ctx, sname, &principal)); + status = ADS_ERROR_KRB5(smb_krb5_parse_name(ctx, sname, &principal)); if (!ADS_ERR_OK(status)) { return status; } -- cgit From 351e749246a278b60a7e18c1eeafdc8ec70efea2 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 25 Apr 2006 12:24:25 +0000 Subject: r15240: Correctly disallow unauthorized access when logging on with the kerberized pam_winbind and workstation restrictions are in effect. The krb5 AS-REQ needs to add the host netbios-name in the address-list. We don't get the clear NT_STATUS_INVALID_WORKSTATION code back yet from the edata of the KRB_ERROR but the login at least fails when the local machine is not in the workstation list on the DC. Guenther (This used to be commit 8b2ba11508e2730aba074d7c095291fac2a62176) --- source3/libads/kerberos.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 960709a5f0..2dfdc31dd5 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -65,6 +65,7 @@ int kerberos_kinit_password_ext(const char *principal, time_t *renew_till_time, const char *cache_name, BOOL request_pac, + BOOL add_netbios_addr, time_t renewable_time) { krb5_context ctx = NULL; @@ -73,6 +74,7 @@ int kerberos_kinit_password_ext(const char *principal, krb5_principal me; krb5_creds my_creds; krb5_get_init_creds_opt opt; + smb_krb5_addresses *addr = NULL; initialize_krb5_error_table(); if ((code = krb5_init_context(&ctx))) @@ -101,19 +103,36 @@ int kerberos_kinit_password_ext(const char *principal, if (request_pac) { #ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PAC_REQUEST - krb5_get_init_creds_opt_set_pac_request(ctx, &opt, True); + code = krb5_get_init_creds_opt_set_pac_request(ctx, &opt, True); + if (code) { + krb5_free_principal(ctx, me); + krb5_free_context(ctx); + return code; + } #endif } + if (add_netbios_addr) { + code = smb_krb5_gen_netbios_krb5_address(&addr); + if (code) { + krb5_free_principal(ctx, me); + krb5_free_context(ctx); + return code; + } + krb5_get_init_creds_opt_set_address_list(&opt, addr->addrs); + } + if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, CONST_DISCARD(char *,password), kerb_prompter, NULL, 0, NULL, &opt))) { + smb_krb5_free_addresses(ctx, addr); krb5_free_principal(ctx, me); krb5_free_context(ctx); return code; } if ((code = krb5_cc_initialize(ctx, cc, me))) { + smb_krb5_free_addresses(ctx, addr); krb5_free_cred_contents(ctx, &my_creds); krb5_free_principal(ctx, me); krb5_free_context(ctx); @@ -122,6 +141,7 @@ int kerberos_kinit_password_ext(const char *principal, if ((code = krb5_cc_store_cred(ctx, cc, &my_creds))) { krb5_cc_close(ctx, cc); + smb_krb5_free_addresses(ctx, addr); krb5_free_cred_contents(ctx, &my_creds); krb5_free_principal(ctx, me); krb5_free_context(ctx); @@ -137,6 +157,7 @@ int kerberos_kinit_password_ext(const char *principal, } krb5_cc_close(ctx, cc); + smb_krb5_free_addresses(ctx, addr); krb5_free_cred_contents(ctx, &my_creds); krb5_free_principal(ctx, me); krb5_free_context(ctx); @@ -178,7 +199,7 @@ int ads_kinit_password(ADS_STRUCT *ads) } ret = kerberos_kinit_password_ext(s, ads->auth.password, ads->auth.time_offset, - &ads->auth.expire, NULL, NULL, False, ads->auth.renewable); + &ads->auth.expire, NULL, NULL, False, False, ads->auth.renewable); if (ret) { DEBUG(0,("kerberos_kinit_password %s failed: %s\n", @@ -812,6 +833,7 @@ int kerberos_kinit_password(const char *principal, 0, cache_name, False, + False, 0); } -- cgit From b86c19795aadd45527694e6002cdd806e928cf38 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 25 Apr 2006 20:13:05 +0000 Subject: r15250: dump some more sids. Guenther (This used to be commit 2922c7f5704e3cfcc80dc648bb3d6d9aa80aaf37) --- source3/libads/ldap.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index c2ebf14d2f..81aa9051d7 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1665,6 +1665,8 @@ static BOOL ads_dump_field(char *field, void **values, void *data_area) {"dnsRecord", False, dump_binary}, {"objectSid", False, dump_sid}, {"tokenGroups", False, dump_sid}, + {"tokenGroupsNoGCAcceptable", False, dump_sid}, + {"tokengroupsGlobalandUniversal", False, dump_sid}, {NULL, True, NULL} }; int i; -- cgit From 34e810076df8720a145f5a619ed648c384898563 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 28 Apr 2006 14:44:43 +0000 Subject: r15305: Let winbind search by sid directly (or in windows terms: "bind to a sid"); works in all AD versions I tested. Also add "net ads sid" search tool. Guenther (This used to be commit 5557ada6943b817d28a5471c613c7291febe2ad5) --- source3/libads/ads_ldap.c | 104 -------------------------------------------- source3/libads/ldap_utils.c | 25 +++++++++++ 2 files changed, 25 insertions(+), 104 deletions(-) delete mode 100644 source3/libads/ads_ldap.c (limited to 'source3/libads') diff --git a/source3/libads/ads_ldap.c b/source3/libads/ads_ldap.c deleted file mode 100644 index 42821496c3..0000000000 --- a/source3/libads/ads_ldap.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Winbind ADS backend functions - - Copyright (C) Andrew Tridgell 2001 - Copyright (C) Andrew Bartlett 2002 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" -#ifdef HAVE_LDAP - -/* convert a sid to a DN */ - -ADS_STATUS ads_sid_to_dn(ADS_STRUCT *ads, - TALLOC_CTX *mem_ctx, - const DOM_SID *sid, - char **dn) -{ - ADS_STATUS rc; - LDAPMessage *msg = NULL; - LDAPMessage *entry = NULL; - char *ldap_exp; - char *sidstr = NULL; - int count; - char *dn2 = NULL; - - const char *attr[] = { - "dn", - NULL - }; - - if (!(sidstr = sid_binstring(sid))) { - DEBUG(1,("ads_sid_to_dn: sid_binstring failed!\n")); - rc = ADS_ERROR_NT(NT_STATUS_NO_MEMORY); - goto done; - } - - if(!(ldap_exp = talloc_asprintf(mem_ctx, "(objectSid=%s)", sidstr))) { - DEBUG(1,("ads_sid_to_dn: talloc_asprintf failed!\n")); - rc = ADS_ERROR_NT(NT_STATUS_NO_MEMORY); - goto done; - } - - rc = ads_search_retry(ads, (void **)(void *)&msg, ldap_exp, attr); - - if (!ADS_ERR_OK(rc)) { - DEBUG(1,("ads_sid_to_dn ads_search: %s\n", ads_errstr(rc))); - goto done; - } - - if ((count = ads_count_replies(ads, msg)) != 1) { - fstring sid_string; - DEBUG(1,("ads_sid_to_dn (sid=%s): Not found (count=%d)\n", - sid_to_string(sid_string, sid), count)); - rc = ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL); - goto done; - } - - entry = ads_first_entry(ads, msg); - - dn2 = ads_get_dn(ads, entry); - - if (!dn2) { - rc = ADS_ERROR_NT(NT_STATUS_NO_MEMORY); - goto done; - } - - *dn = talloc_strdup(mem_ctx, dn2); - - if (!*dn) { - rc = ADS_ERROR_NT(NT_STATUS_NO_MEMORY); - goto done; - } - - rc = ADS_ERROR_NT(NT_STATUS_OK); - - DEBUG(3,("ads sid_to_dn mapped %s\n", dn2)); - - SAFE_FREE(dn2); -done: - if (msg) ads_msgfree(ads, msg); - if (dn2) ads_memfree(ads, dn2); - - SAFE_FREE(sidstr); - - return rc; -} - -#endif diff --git a/source3/libads/ldap_utils.c b/source3/libads/ldap_utils.c index 18caa2c63a..105fd2e5b9 100644 --- a/source3/libads/ldap_utils.c +++ b/source3/libads/ldap_utils.c @@ -105,4 +105,29 @@ ADS_STATUS ads_search_retry_dn(ADS_STRUCT *ads, void **res, return ads_do_search_retry(ads, dn, LDAP_SCOPE_BASE, "(objectclass=*)", attrs, res); } + +ADS_STATUS ads_search_retry_sid(ADS_STRUCT *ads, void **res, + const DOM_SID *sid, + const char **attrs) +{ + char *dn, *sid_string; + ADS_STATUS status; + + sid_string = sid_binstring_hex(sid); + if (sid_string == NULL) { + return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + } + + if (!asprintf(&dn, "", sid_string)) { + SAFE_FREE(sid_string); + return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + } + + status = ads_do_search_retry(ads, dn, LDAP_SCOPE_BASE, + "(objectclass=*)", attrs, res); + SAFE_FREE(dn); + SAFE_FREE(sid_string); + return status; +} + #endif -- cgit From 359aed77c938ff36143c2bdddd1ae0514cb29388 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 2 May 2006 11:54:18 +0000 Subject: r15392: In most cases, this mapping is more appropriate. (I know, it is still a mess, but there is no way the get NTSTATUS from the edata yet). Guenther (This used to be commit be2bd3945c057a4ad72251f809cffbe4694a7e3d) --- source3/libads/krb5_errs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/krb5_errs.c b/source3/libads/krb5_errs.c index 0c2e704702..e73482522b 100644 --- a/source3/libads/krb5_errs.c +++ b/source3/libads/krb5_errs.c @@ -40,7 +40,7 @@ static const struct { #endif {25, NT_STATUS_PASSWORD_EXPIRED}, /* FIXME: bug in heimdal 0.7 krb5_get_init_creds_password (Inappropriate ioctl for device (25)) */ {KRB5KDC_ERR_NULL_KEY, NT_STATUS_LOGON_FAILURE}, - {KRB5KDC_ERR_POLICY, NT_STATUS_PASSWORD_RESTRICTION}, + {KRB5KDC_ERR_POLICY, NT_STATUS_INVALID_WORKSTATION}, {KRB5KDC_ERR_PREAUTH_FAILED, NT_STATUS_LOGON_FAILURE}, {KRB5KDC_ERR_SERVICE_REVOKED, NT_STATUS_ACCESS_DENIED}, {KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN, NT_STATUS_INVALID_ACCOUNT_NAME}, -- cgit From 3bff11407e721a4a01b67881862d2a466ec5d103 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 5 May 2006 15:54:11 +0000 Subject: r15461: Free LDAP result in ads_get_attrname_by_oid(). Guenther (This used to be commit f4af888282ff39665f186550b9ccbbf7a9128fc2) --- source3/libads/ldap.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 81aa9051d7..a8877b5697 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2471,6 +2471,7 @@ const char *ads_get_attrname_by_oid(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const void *res = NULL; char *expr = NULL; const char *attrs[] = { "lDAPDisplayName", NULL }; + char *result; if (ads == NULL || mem_ctx == NULL || OID == NULL) { goto failed; @@ -2492,12 +2493,16 @@ const char *ads_get_attrname_by_oid(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const goto failed; } - return ads_pull_string(ads, mem_ctx, res, "lDAPDisplayName"); + result = ads_pull_string(ads, mem_ctx, res, "lDAPDisplayName"); + ads_msgfree(ads, res); + + return result; failed: DEBUG(0,("ads_get_attrname_by_oid: failed to retrieve name for oid: %s\n", OID)); + ads_msgfree(ads, res); return NULL; } -- cgit From af086da4ec19de83717820de85d8e672850ed4b2 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 5 May 2006 19:24:48 +0000 Subject: r15462: replace the use of OpenLDAP's ldap_domain2hostlist() for locating AD DC's with out own DNS SRV queries. Testing on Linux and Solaris. (This used to be commit cf71f88a3cdcabf99c0798ef4cf8c978397a57eb) --- source3/libads/dns.c | 353 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 353 insertions(+) create mode 100644 source3/libads/dns.c (limited to 'source3/libads') diff --git a/source3/libads/dns.c b/source3/libads/dns.c new file mode 100644 index 0000000000..0119ae9130 --- /dev/null +++ b/source3/libads/dns.c @@ -0,0 +1,353 @@ +/* + Unix SMB/CIFS implementation. + DNS utility library + Copyright (C) Gerald (Jerry) Carter 2006. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +/* AIX resolv.h uses 'class' in struct ns_rr */ + +#if defined(AIX) +# if defined(class) +# undef class +# endif +#endif /* AIX */ + +/* resolver headers */ + +#include +#include +#include +#include +#include + +#define MAX_DNS_PACKET_SIZE 0xffff + +/********************************************************************* +*********************************************************************/ + +static BOOL ads_dns_parse_query( TALLOC_CTX *ctx, uint8 *start, uint8 *end, + uint8 **ptr, struct dns_query *q ) +{ + uint8 *p = *ptr; + pstring hostname; + int namelen; + + ZERO_STRUCTP( q ); + + if ( !start || !end || !q || !*ptr) + return False; + + /* See RFC 1035 for details. If this fails, then return. */ + + namelen = dn_expand( start, end, p, hostname, sizeof(hostname) ); + if ( namelen < 0 ) { + return False; + } + p += namelen; + q->hostname = talloc_strdup( ctx, hostname ); + + /* check that we have space remaining */ + + if ( PTR_DIFF(p+4, end) > 0 ) + return False; + + q->type = RSVAL( p, 0 ); + q->in_class = RSVAL( p, 2 ); + p += 4; + + *ptr = p; + + return True; +} + +/********************************************************************* +*********************************************************************/ + +static BOOL ads_dns_parse_rr( TALLOC_CTX *ctx, uint8 *start, uint8 *end, + uint8 **ptr, struct dns_rr *rr ) +{ + uint8 *p = *ptr; + pstring hostname; + int namelen; + + if ( !start || !end || !rr || !*ptr) + return -1; + + ZERO_STRUCTP( rr ); + /* pull the name from the answer */ + + namelen = dn_expand( start, end, p, hostname, sizeof(hostname) ); + if ( namelen < 0 ) { + return -1; + } + p += namelen; + rr->hostname = talloc_strdup( ctx, hostname ); + + /* check that we have space remaining */ + + if ( PTR_DIFF(p+10, end) > 0 ) + return False; + + /* pull some values and then skip onto the string */ + + rr->type = RSVAL(p, 0); + rr->in_class = RSVAL(p, 2); + rr->ttl = RIVAL(p, 4); + rr->rdatalen = RSVAL(p, 8); + + p += 10; + + /* sanity check the available space */ + + if ( PTR_DIFF(p+rr->rdatalen, end ) > 0 ) { + return False; + + } + + /* save a point to the rdata for this section */ + + rr->rdata = p; + p += rr->rdatalen; + + *ptr = p; + + return True; +} + +/********************************************************************* +*********************************************************************/ + +static BOOL ads_dns_parse_rr_srv( TALLOC_CTX *ctx, uint8 *start, uint8 *end, + uint8 **ptr, struct dns_rr_srv *srv ) +{ + struct dns_rr rr; + uint8 *p; + pstring dcname; + int namelen; + + if ( !start || !end || !srv || !*ptr) + return -1; + + /* Parse the RR entry. Coming out of the this, ptr is at the beginning + of the next record */ + + if ( !ads_dns_parse_rr( ctx, start, end, ptr, &rr ) ) { + DEBUG(1,("ads_dns_parse_rr_srv: Failed to parse RR record\n")); + return False; + } + + if ( rr.type != ns_t_srv ) { + DEBUG(1,("ads_dns_parse_rr_srv: Bad answer type (%d)\n", rr.type)); + return False; + } + + p = rr.rdata; + + srv->priority = RSVAL(p, 0); + srv->weight = RSVAL(p, 2); + srv->port = RSVAL(p, 4); + + p += 6; + + namelen = dn_expand( start, end, p, dcname, sizeof(dcname) ); + if ( namelen < 0 ) { + DEBUG(1,("ads_dns_parse_rr_srv: Failed to uncompress name!\n")); + return False; + } + srv->hostname = talloc_strdup( ctx, dcname ); + + return True; +} + + +/********************************************************************* + Sort SRV record list based on weight and priority. See RFC 2782. +*********************************************************************/ + +static int dnssrvcmp( struct dns_rr_srv *a, struct dns_rr_srv *b ) +{ + BOOL init = False; + + if ( !init ) { + srand( (uint32)time(NULL) ); + } + + if ( a->priority == b->priority ) { + + /* randomize entries with an equal weight and priority */ + if ( a->weight == b->weight ) + return rand() % 2 ? -1 : 1; + + /* higher weights should be sorted lower */ + if ( a->weight > b->weight ) + return -1; + else + return 1; + } + + if ( a->priority < b->priority ) + return -1; + + return 1; +} + +/********************************************************************* + Simple wrapper for a DNS SRV query +*********************************************************************/ + +NTSTATUS ads_dns_lookup_srv( TALLOC_CTX *ctx, const char *name, struct dns_rr_srv **dclist, int *numdcs ) +{ + uint8 *buffer = NULL; + size_t buf_len; + int resp_len = NS_PACKETSZ; + struct dns_rr_srv *dcs = NULL; + int query_count, answer_count, auth_count, additional_count; + uint8 *p = buffer; + int rrnum; + int idx = 0; + + if ( !ctx || !name || !dclist ) { + return NT_STATUS_INVALID_PARAMETER; + } + + /* Send the request. May have to loop several times in case + of large replies */ + + do { + if ( buffer ) + TALLOC_FREE( buffer ); + + buf_len = resp_len * sizeof(uint8); + + if ( (buffer = TALLOC_ARRAY(ctx, uint8, buf_len)) == NULL ) { + DEBUG(0,("ads_dns_lookup_srv: talloc() failed!\n")); + return NT_STATUS_NO_MEMORY; + } + + if ( (resp_len = res_query(name, ns_c_in, ns_t_srv, buffer, buf_len)) < 0 ) { + DEBUG(1,("ads_dns_lookup_srv: Failed to resolve %s (%s)\n", name, strerror(errno))); + TALLOC_FREE( buffer ); + return NT_STATUS_UNSUCCESSFUL; + } + } while ( buf_len < resp_len && resp_len < MAX_DNS_PACKET_SIZE ); + + p = buffer; + + /* For some insane reason, the ns_initparse() et. al. routines are only + available in libresolv.a, and not the shared lib. Who knows why.... + So we have to parse the DNS reply ourselves */ + + /* Pull the answer RR's count from the header. Use the NMB ordering macros */ + + query_count = RSVAL( p, 4 ); + answer_count = RSVAL( p, 6 ); + auth_count = RSVAL( p, 8 ); + additional_count = RSVAL( p, 10 ); + + DEBUG(4,("ads_dns_lookup_srv: %d records returned in the answer section.\n", + answer_count)); + + if ( (dcs = TALLOC_ARRAY(ctx, struct dns_rr_srv, answer_count)) == NULL ) { + DEBUG(0,("ads_dns_lookup_srv: talloc() failure for %d char*'s\n", + answer_count)); + return NT_STATUS_NO_MEMORY; + } + + /* now skip the header */ + + p += NS_HFIXEDSZ; + + /* parse the query section */ + + for ( rrnum=0; rrnum Date: Fri, 5 May 2006 20:18:50 +0000 Subject: r15463: compile fix for new DNS code for machine using Bind 4 libs (old IRIX host) (This used to be commit b0160f893393a446927c751961d101ddbcba4db4) --- source3/libads/dns.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/dns.c b/source3/libads/dns.c index 0119ae9130..678124a5e9 100644 --- a/source3/libads/dns.c +++ b/source3/libads/dns.c @@ -38,6 +38,14 @@ #define MAX_DNS_PACKET_SIZE 0xffff +#ifndef NS_HFIXEDSZ +# ifdef HFIXEDSZ +# define NS_HFIXEDSZ HFIXEDSZ +# else +# define NS_HFIXEDSZ 12 +# endif +#endif + /********************************************************************* *********************************************************************/ -- cgit From b62f60d736ebc99ca688d577d5f4987100744f2a Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 5 May 2006 21:19:25 +0000 Subject: r15464: fix dns build breakage on IRIX and OpenBSD (This used to be commit 43f5d09a164ae111807222bdcbef949206766097) --- source3/libads/dns.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/dns.c b/source3/libads/dns.c index 678124a5e9..7eeb915ecf 100644 --- a/source3/libads/dns.c +++ b/source3/libads/dns.c @@ -38,12 +38,17 @@ #define MAX_DNS_PACKET_SIZE 0xffff -#ifndef NS_HFIXEDSZ +#ifdef NS_HFIXEDSZ /* Bind 8/9 interface */ +# define C_IN ns_c_in +# define T_A ns_t_a +# define T_SRV ns_t_srv +#else # ifdef HFIXEDSZ # define NS_HFIXEDSZ HFIXEDSZ # else -# define NS_HFIXEDSZ 12 +# define NS_HFIXEDSZ sizeof(HEADER) # endif +# define T_SRV 33 #endif /********************************************************************* @@ -160,7 +165,7 @@ static BOOL ads_dns_parse_rr_srv( TALLOC_CTX *ctx, uint8 *start, uint8 *end, return False; } - if ( rr.type != ns_t_srv ) { + if ( rr.type != T_SRV ) { DEBUG(1,("ads_dns_parse_rr_srv: Bad answer type (%d)\n", rr.type)); return False; } @@ -248,7 +253,7 @@ NTSTATUS ads_dns_lookup_srv( TALLOC_CTX *ctx, const char *name, struct dns_rr_sr return NT_STATUS_NO_MEMORY; } - if ( (resp_len = res_query(name, ns_c_in, ns_t_srv, buffer, buf_len)) < 0 ) { + if ( (resp_len = res_query(name, C_IN, T_SRV, buffer, buf_len)) < 0 ) { DEBUG(1,("ads_dns_lookup_srv: Failed to resolve %s (%s)\n", name, strerror(errno))); TALLOC_FREE( buffer ); return NT_STATUS_UNSUCCESSFUL; @@ -328,7 +333,7 @@ NTSTATUS ads_dns_lookup_srv( TALLOC_CTX *ctx, const char *name, struct dns_rr_sr /* only interested in A records as a shortcut for having to come back later and lookup the name */ - if ( (rr.type != ns_t_a) || (rr.rdatalen != 4) ) + if ( (rr.type != T_A) || (rr.rdatalen != 4) ) continue; for ( i=0; i Date: Sun, 7 May 2006 15:05:32 +0000 Subject: r15492: Without this patch, the LDAP client libs will call abort() in ldap_get_values_len, because they were handed a NULL msgs pointer, for example in ads_pull_sid(). This occurs when the AD server fails at the connect stage. (The toubled AD server is actually Samba4 in my example). Andrew Bartlett (This used to be commit 221a6de7d028f5c9bb9da038650868582d44e7e5) --- source3/libads/ldap_utils.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap_utils.c b/source3/libads/ldap_utils.c index 105fd2e5b9..58f1c20ad2 100644 --- a/source3/libads/ldap_utils.c +++ b/source3/libads/ldap_utils.c @@ -48,15 +48,16 @@ ADS_STATUS ads_do_search_retry(ADS_STRUCT *ads, const char *bind_path, int scope return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); } - while (count--) { - *res = NULL; - status = ads_do_search_all(ads, bp, scope, expr, attrs, res); - if (ADS_ERR_OK(status)) { - DEBUG(5,("Search for %s gave %d replies\n", - expr, ads_count_replies(ads, *res))); - SAFE_FREE(bp); - return status; - } + *res = NULL; + status = ads_do_search_all(ads, bp, scope, expr, attrs, res); + if (ADS_ERR_OK(status)) { + DEBUG(5,("Search for %s gave %d replies\n", + expr, ads_count_replies(ads, *res))); + SAFE_FREE(bp); + return status; + } + + while (--count) { if (*res) ads_msgfree(ads, *res); @@ -79,6 +80,15 @@ ADS_STATUS ads_do_search_retry(ADS_STRUCT *ads, const char *bind_path, int scope SAFE_FREE(bp); return status; } + + *res = NULL; + status = ads_do_search_all(ads, bp, scope, expr, attrs, res); + if (ADS_ERR_OK(status)) { + DEBUG(5,("Search for %s gave %d replies\n", + expr, ads_count_replies(ads, *res))); + SAFE_FREE(bp); + return status; + } } SAFE_FREE(bp); -- cgit From f7776975080c88bec9013ccac8185c582e818e54 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 9 May 2006 19:02:26 +0000 Subject: r15523: Honour the time_offset also when verifying kerberos tickets. This prevents a nasty failure condition in winbindd's pam_auth where a tgt and a service ticket could have been succefully retrieved, but just not validated. Guenther (This used to be commit a75dd80c6210d01aff104a86b0a9d39d65f2c348) --- source3/libads/kerberos_verify.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index fa957aa9c0..525a9cfa27 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -286,7 +286,8 @@ static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context au ***********************************************************************************/ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, - const char *realm, const DATA_BLOB *ticket, + const char *realm, time_t time_offset, + const DATA_BLOB *ticket, char **principal, PAC_DATA **pac_data, DATA_BLOB *ap_rep, DATA_BLOB *session_key) @@ -323,6 +324,10 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, return NT_STATUS_LOGON_FAILURE; } + if (time_offset != 0) { + krb5_set_real_time(context, time(NULL) + time_offset, 0); + } + ret = krb5_set_default_realm(context, realm); if (ret) { DEBUG(1,("ads_verify_ticket: krb5_set_default_realm failed (%s)\n", error_message(ret))); -- cgit From 2c029a8b96ae476f1d5c2abe14ee25f98a1513d8 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 12 May 2006 15:17:35 +0000 Subject: r15543: New implementation of 'net ads join' to be more like Windows XP. The motivating factor is to not require more privileges for the user account than Windows does when joining a domain. The points of interest are * net_ads_join() uses same rpc mechanisms as net_rpc_join() * Enable CLDAP queries for filling in the majority of the ADS_STRUCT->config information * Remove ldap_initialized() from sam/idmap_ad.c and libads/ldap.c * Remove some unnecessary fields from ADS_STRUCT * Manually set the dNSHostName and servicePrincipalName attribute using the machine account after the join Thanks to Guenther and Simo for the review. Still to do: * Fix the userAccountControl for DES only systems * Set the userPrincipalName in order to support things like 'kinit -k' (although we might be able to just use the sAMAccountName instead) * Re-add support for pre-creating the machine account in a specific OU (This used to be commit 4c4ea7b20f44cd200cef8c7b389d51b72eccc39b) --- source3/libads/ads_struct.c | 6 +- source3/libads/cldap.c | 278 +++++++++++++++++++++++++++++++++ source3/libads/ldap.c | 363 +++++++++++++++++++------------------------- 3 files changed, 441 insertions(+), 206 deletions(-) create mode 100644 source3/libads/cldap.c (limited to 'source3/libads') diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index 9b2179ad31..48533c7ffb 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -118,12 +118,13 @@ void ads_destroy(ADS_STRUCT **ads) is_mine = (*ads)->is_mine; #if HAVE_LDAP - if ((*ads)->ld) ldap_unbind((*ads)->ld); + if ((*ads)->ld) { + ldap_unbind((*ads)->ld); + } #endif SAFE_FREE((*ads)->server.realm); SAFE_FREE((*ads)->server.workgroup); SAFE_FREE((*ads)->server.ldap_server); - SAFE_FREE((*ads)->server.ldap_uri); SAFE_FREE((*ads)->auth.realm); SAFE_FREE((*ads)->auth.password); @@ -132,7 +133,6 @@ void ads_destroy(ADS_STRUCT **ads) SAFE_FREE((*ads)->config.realm); SAFE_FREE((*ads)->config.bind_path); - SAFE_FREE((*ads)->config.schema_path); SAFE_FREE((*ads)->config.ldap_server_name); SAFE_FREE((*ads)->schema.sfu_uidnumber_attr); diff --git a/source3/libads/cldap.c b/source3/libads/cldap.c new file mode 100644 index 0000000000..6a62f573c9 --- /dev/null +++ b/source3/libads/cldap.c @@ -0,0 +1,278 @@ +/* + Samba Unix/Linux SMB client library + net ads cldap functions + Copyright (C) 2001 Andrew Tridgell (tridge@samba.org) + Copyright (C) 2003 Jim McDonough (jmcd@us.ibm.com) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +/* + These seem to be strings as described in RFC1035 4.1.4 and can be: + + - a sequence of labels ending in a zero octet + - a pointer + - a sequence of labels ending with a pointer + + A label is a byte where the first two bits must be zero and the remaining + bits represent the length of the label followed by the label itself. + Therefore, the length of a label is at max 64 bytes. Under RFC1035, a + sequence of labels cannot exceed 255 bytes. + + A pointer consists of a 14 bit offset from the beginning of the data. + + struct ptr { + unsigned ident:2; // must be 11 + unsigned offset:14; // from the beginning of data + }; + + This is used as a method to compress the packet by eliminated duplicate + domain components. Since a UDP packet should probably be < 512 bytes and a + DNS name can be up to 255 bytes, this actually makes a lot of sense. +*/ +static unsigned pull_netlogon_string(char *ret, const char *ptr, + const char *data) +{ + char *pret = ret; + int followed_ptr = 0; + unsigned ret_len = 0; + + memset(pret, 0, MAX_DNS_LABEL); + do { + if ((*ptr & 0xc0) == 0xc0) { + uint16 len; + + if (!followed_ptr) { + ret_len += 2; + followed_ptr = 1; + } + len = ((ptr[0] & 0x3f) << 8) | ptr[1]; + ptr = data + len; + } else if (*ptr) { + uint8 len = (uint8)*(ptr++); + + if ((pret - ret + len + 1) >= MAX_DNS_LABEL) { + d_fprintf(stderr, "DC returning too long DNS name\n"); + return 0; + } + + if (pret != ret) { + *pret = '.'; + pret++; + } + memcpy(pret, ptr, len); + pret += len; + ptr += len; + + if (!followed_ptr) { + ret_len += (len + 1); + } + } + } while (*ptr); + + return followed_ptr ? ret_len : ret_len + 1; +} + +/* + do a cldap netlogon query +*/ +static int send_cldap_netlogon(int sock, const char *domain, + const char *hostname, unsigned ntversion) +{ + ASN1_DATA data; + char ntver[4]; +#ifdef CLDAP_USER_QUERY + char aac[4]; + + SIVAL(aac, 0, 0x00000180); +#endif + SIVAL(ntver, 0, ntversion); + + memset(&data, 0, sizeof(data)); + + asn1_push_tag(&data,ASN1_SEQUENCE(0)); + asn1_write_Integer(&data, 4); + asn1_push_tag(&data, ASN1_APPLICATION(3)); + asn1_write_OctetString(&data, NULL, 0); + asn1_write_enumerated(&data, 0); + asn1_write_enumerated(&data, 0); + asn1_write_Integer(&data, 0); + asn1_write_Integer(&data, 0); + asn1_write_BOOLEAN2(&data, False); + asn1_push_tag(&data, ASN1_CONTEXT(0)); + + asn1_push_tag(&data, ASN1_CONTEXT(3)); + asn1_write_OctetString(&data, "DnsDomain", 9); + asn1_write_OctetString(&data, domain, strlen(domain)); + asn1_pop_tag(&data); + + asn1_push_tag(&data, ASN1_CONTEXT(3)); + asn1_write_OctetString(&data, "Host", 4); + asn1_write_OctetString(&data, hostname, strlen(hostname)); + asn1_pop_tag(&data); + +#ifdef CLDAP_USER_QUERY + asn1_push_tag(&data, ASN1_CONTEXT(3)); + asn1_write_OctetString(&data, "User", 4); + asn1_write_OctetString(&data, "SAMBA$", 6); + asn1_pop_tag(&data); + + asn1_push_tag(&data, ASN1_CONTEXT(3)); + asn1_write_OctetString(&data, "AAC", 4); + asn1_write_OctetString(&data, aac, 4); + asn1_pop_tag(&data); +#endif + + asn1_push_tag(&data, ASN1_CONTEXT(3)); + asn1_write_OctetString(&data, "NtVer", 5); + asn1_write_OctetString(&data, ntver, 4); + asn1_pop_tag(&data); + + asn1_pop_tag(&data); + + asn1_push_tag(&data,ASN1_SEQUENCE(0)); + asn1_write_OctetString(&data, "NetLogon", 8); + asn1_pop_tag(&data); + asn1_pop_tag(&data); + asn1_pop_tag(&data); + + if (data.has_error) { + d_fprintf(stderr, "Failed to build cldap netlogon at offset %d\n", (int)data.ofs); + asn1_free(&data); + return -1; + } + + if (write(sock, data.data, data.length) != (ssize_t)data.length) { + d_fprintf(stderr, "failed to send cldap query (%s)\n", strerror(errno)); + } + + asn1_free(&data); + + return 0; +} + + +/* + receive a cldap netlogon reply +*/ +static int recv_cldap_netlogon(int sock, struct cldap_netlogon_reply *reply) +{ + int ret; + ASN1_DATA data; + DATA_BLOB blob; + DATA_BLOB os1, os2, os3; + int i1; + char *p; + + blob = data_blob(NULL, 8192); + + ret = read(sock, blob.data, blob.length); + + if (ret <= 0) { + d_fprintf(stderr, "no reply received to cldap netlogon\n"); + 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) { + d_fprintf(stderr, "Failed to parse cldap reply\n"); + return -1; + } + + p = (char *)os3.data; + + reply->type = IVAL(p, 0); p += 4; + reply->flags = IVAL(p, 0); p += 4; + + memcpy(&reply->guid.info, p, UUID_FLAT_SIZE); + p += UUID_FLAT_SIZE; + + p += pull_netlogon_string(reply->forest, p, (const char *)os3.data); + p += pull_netlogon_string(reply->domain, p, (const char *)os3.data); + p += pull_netlogon_string(reply->hostname, p, (const char *)os3.data); + p += pull_netlogon_string(reply->netbios_domain, p, (const char *)os3.data); + p += pull_netlogon_string(reply->netbios_hostname, p, (const char *)os3.data); + p += pull_netlogon_string(reply->unk, p, (const char *)os3.data); + + if (reply->type == SAMLOGON_AD_R) { + p += pull_netlogon_string(reply->user_name, p, (const char *)os3.data); + } else { + *reply->user_name = 0; + } + + p += pull_netlogon_string(reply->site_name, p, (const char *)os3.data); + p += pull_netlogon_string(reply->site_name_2, p, (const char *)os3.data); + + reply->version = IVAL(p, 0); + reply->lmnt_token = SVAL(p, 4); + reply->lm20_token = SVAL(p, 6); + + data_blob_free(&os1); + data_blob_free(&os2); + data_blob_free(&os3); + data_blob_free(&blob); + + return 0; +} + +/******************************************************************* + do a cldap netlogon query. Always 389/udp +*******************************************************************/ + +BOOL ads_cldap_netlogon(const char *server, const char *realm, struct cldap_netlogon_reply *reply) +{ + int sock; + int ret; + + sock = open_udp_socket(server, LDAP_PORT ); + if (sock == -1) { + DEBUG(2,("ads_cldap_netlogon: Failed to open udp socket to %s\n", + server)); + return False; + } + + ret = send_cldap_netlogon(sock, realm, global_myname(), 6); + if (ret != 0) { + return False; + } + ret = recv_cldap_netlogon(sock, reply); + close(sock); + + if (ret == -1) { + return False; + } + + return True; +} + + diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index a8877b5697..6f698dc3a9 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -112,31 +112,52 @@ static int ldap_search_with_timeout(LDAP *ld, /* try a connection to a given ldap server, returning True and setting the servers IP in the ads struct if successful - - TODO : add a negative connection cache in here leveraged off of the one - found in the rpc code. --jerry */ -BOOL ads_try_connect(ADS_STRUCT *ads, const char *server, unsigned port) +BOOL ads_try_connect(ADS_STRUCT *ads, const char *server ) { char *srv; + struct cldap_netlogon_reply cldap_reply; if (!server || !*server) { return False; } - - DEBUG(5,("ads_try_connect: trying ldap server '%s' port %u\n", server, port)); + + DEBUG(5,("ads_try_connect: sending CLDAP request to %s\n", server)); /* this copes with inet_ntoa brokenness */ + srv = SMB_STRDUP(server); - ads->ld = ldap_open_with_timeout(srv, port, lp_ldap_timeout()); - if (!ads->ld) { - free(srv); + ZERO_STRUCT( cldap_reply ); + + if ( !ads_cldap_netlogon( srv, ads->server.realm, &cldap_reply ) ) { + DEBUG(3,("ads_try_connect: CLDAP request %s failed.\n", srv)); return False; } - ads->ldap_port = port; + + /* Check the CLDAP reply flags */ + + if ( !(cldap_reply.flags & ADS_LDAP) ) { + DEBUG(1,("ads_try_connect: %s's CLDAP reply says it is not an LDAP server!\n", + srv)); + SAFE_FREE( srv ); + return False; + } + + /* Fill in the ads->config values */ + + SAFE_FREE(ads->config.realm); + SAFE_FREE(ads->config.bind_path); + SAFE_FREE(ads->config.ldap_server_name); + + ads->config.ldap_server_name = SMB_STRDUP(cldap_reply.hostname); + strupper_m(cldap_reply.domain); + ads->config.realm = SMB_STRDUP(cldap_reply.domain); + ads->config.bind_path = ads_build_dn(ads->config.realm); + + ads->ldap_port = LDAP_PORT; ads->ldap_ip = *interpret_addr2(srv); - free(srv); + SAFE_FREE(srv); /* cache the successful connection */ @@ -145,29 +166,6 @@ BOOL ads_try_connect(ADS_STRUCT *ads, const char *server, unsigned port) return True; } -/* - try a connection to a given ldap server, based on URL, returning True if successful - */ -static BOOL ads_try_connect_uri(ADS_STRUCT *ads) -{ -#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) - DEBUG(5,("ads_try_connect: trying ldap server at URI '%s'\n", - ads->server.ldap_uri)); - - - if (ldap_initialize((LDAP**)&(ads->ld), ads->server.ldap_uri) == LDAP_SUCCESS) { - return True; - } - DEBUG(0, ("ldap_initialize: %s\n", strerror(errno))); - -#else - - DEBUG(1, ("no URL support in LDAP libs!\n")); -#endif - - return False; -} - /********************************************************************** Try to find an AD dc using our internal name resolution routines Try the realm first and then then workgroup name if netbios is not @@ -233,8 +231,6 @@ again: /* if we fail this loop, then giveup since all the IP addresses returned were dead */ for ( i=0; ilast_attempt = time(NULL); ads->ld = NULL; - /* try with a URL based server */ - - if (ads->server.ldap_uri && - ads_try_connect_uri(ads)) { - goto got_connection; - } - /* try with a user specified server */ + if (ads->server.ldap_server && - ads_try_connect(ads, ads->server.ldap_server, LDAP_PORT)) { + ads_try_connect(ads, ads->server.ldap_server)) { goto got_connection; } @@ -292,22 +282,12 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) got_connection: DEBUG(3,("Connected to LDAP server %s\n", inet_ntoa(ads->ldap_ip))); - status = ads_server_info(ads); - if (!ADS_ERR_OK(status)) { - DEBUG(1,("Failed to get ldap server info\n")); - return status; - } - - ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); - - status = ADS_ERROR(smb_ldap_start_tls(ads->ld, version)); - if (!ADS_ERR_OK(status)) { - return status; - } - if (!ads->auth.user_name) { /* have to use the userPrincipalName value here and - not servicePrincipalName; found by Guenther Deschner @ Sernet */ + not servicePrincipalName; found by Guenther Deschner @ Sernet. + + Is this still correct? The comment does not match + the code. --jerry */ asprintf(&ads->auth.user_name, "host/%s", global_myname() ); } @@ -331,10 +311,35 @@ got_connection: } #endif + /* If the caller() requested no LDAP bind, then we are done */ + if (ads->auth.flags & ADS_AUTH_NO_BIND) { return ADS_SUCCESS; } + + /* Otherwise setup the TCP LDAP session */ + + if ( (ads->ld = ldap_open_with_timeout(ads->config.ldap_server_name, + LDAP_PORT, lp_ldap_timeout())) == NULL ) + { + return ADS_ERROR(LDAP_OPERATIONS_ERROR); + } + ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); + + status = ADS_ERROR(smb_ldap_start_tls(ads->ld, version)); + if (!ADS_ERR_OK(status)) { + return status; + } + + /* fill in the current time and offsets */ + + status = ads_current_time( ads ); + if ( !ADS_ERR_OK(status) ) { + return status; + } + /* Now do the bind */ + if (ads->auth.flags & ADS_AUTH_ANON_BIND) { return ADS_ERROR(ldap_simple_bind_s( ads->ld, NULL, NULL)); } @@ -2464,7 +2469,7 @@ static time_t ads_parse_time(const char *str) } -const char *ads_get_attrname_by_oid(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char * OID) +const char *ads_get_attrname_by_oid(ADS_STRUCT *ads, const char *schema_path, TALLOC_CTX *mem_ctx, const char * OID) { ADS_STATUS rc; int count = 0; @@ -2482,8 +2487,8 @@ const char *ads_get_attrname_by_oid(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const goto failed; } - rc = ads_do_search_retry(ads, ads->config.schema_path, - LDAP_SCOPE_SUBTREE, expr, attrs, &res); + rc = ads_do_search_retry(ads, schema_path, LDAP_SCOPE_SUBTREE, + expr, attrs, &res); if (!ADS_ERR_OK(rc)) { goto failed; } @@ -2513,97 +2518,94 @@ failed: * @param ads connection to ads server * @return status of search **/ -ADS_STATUS ads_server_info(ADS_STRUCT *ads) +ADS_STATUS ads_current_time(ADS_STRUCT *ads) { - const char *attrs[] = {"ldapServiceName", - "currentTime", - "schemaNamingContext", NULL}; + const char *attrs[] = {"currentTime", NULL}; ADS_STATUS status; void *res; - char *value; - char *p; char *timestr; - char *schema_path; TALLOC_CTX *ctx; + ADS_STRUCT *ads_s = ads; if (!(ctx = talloc_init("ads_server_info"))) { return ADS_ERROR(LDAP_NO_MEMORY); } - status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); - if (!ADS_ERR_OK(status)) { - talloc_destroy(ctx); - return status; - } + /* establish a new ldap tcp session if necessary */ - value = ads_pull_string(ads, ctx, res, "ldapServiceName"); - if (!value) { - ads_msgfree(ads, res); - talloc_destroy(ctx); - return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); + if ( !ads->ld ) { + if ( (ads_s = ads_init( ads->server.realm, ads->server.workgroup, + ads->server.ldap_server )) == NULL ) + { + goto done; + } + ads_s->auth.flags = ADS_AUTH_ANON_BIND; + status = ads_connect( ads_s ); + if ( !ADS_ERR_OK(status)) + goto done; } - timestr = ads_pull_string(ads, ctx, res, "currentTime"); - if (!timestr) { - ads_msgfree(ads, res); + status = ads_do_search(ads_s, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); + if (!ADS_ERR_OK(status)) { talloc_destroy(ctx); - return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); + goto done; } - schema_path = ads_pull_string(ads, ctx, res, "schemaNamingContext"); - if (!schema_path) { + timestr = ads_pull_string(ads_s, ctx, res, "currentTime"); + if (!timestr) { ads_msgfree(ads, res); talloc_destroy(ctx); - return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); + status = ADS_ERROR(LDAP_NO_RESULTS_RETURNED); + goto done; } - SAFE_FREE(ads->config.schema_path); - ads->config.schema_path = SMB_STRDUP(schema_path); - - ads_msgfree(ads, res); + /* but save the time and offset in the original ADS_STRUCT */ + + ads->config.current_time = ads_parse_time(timestr); - p = strchr(value, ':'); - if (!p) { - talloc_destroy(ctx); - DEBUG(1, ("ads_server_info: returned ldap server name did not contain a ':' " - "so was deemed invalid\n")); - return ADS_ERROR(LDAP_DECODING_ERROR); + if (ads->config.current_time != 0) { + ads->auth.time_offset = ads->config.current_time - time(NULL); + DEBUG(4,("time offset is %d seconds\n", ads->auth.time_offset)); } - SAFE_FREE(ads->config.ldap_server_name); + status = ADS_SUCCESS; - ads->config.ldap_server_name = SMB_STRDUP(p+1); - p = strchr(ads->config.ldap_server_name, '$'); - if (!p || p[1] != '@') { - talloc_destroy(ctx); - DEBUG(1, ("ads_server_info: returned ldap server name (%s) does not contain '$@'" - " so was deemed invalid\n", ads->config.ldap_server_name)); - SAFE_FREE(ads->config.ldap_server_name); - return ADS_ERROR(LDAP_DECODING_ERROR); +done: + /* free any temporary ads connections */ + if ( ads_s != ads ) { + ads_destroy( &ads_s ); } + talloc_destroy(ctx); - *p = 0; + return status; +} - SAFE_FREE(ads->config.realm); - SAFE_FREE(ads->config.bind_path); +/********************************************************************* +*********************************************************************/ - ads->config.realm = SMB_STRDUP(p+2); - ads->config.bind_path = ads_build_dn(ads->config.realm); +static ADS_STATUS ads_schema_path(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char **schema_path) +{ + ADS_STATUS status; + void *res; + const char *schema; + const char *attrs[] = { "schemaNamingContext", NULL }; - DEBUG(3,("got ldap server name %s@%s, using bind path: %s\n", - ads->config.ldap_server_name, ads->config.realm, - ads->config.bind_path)); + status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); + if (!ADS_ERR_OK(status)) { + return status; + } - ads->config.current_time = ads_parse_time(timestr); + if ( (schema = ads_pull_string(ads, mem_ctx, res, "schemaNamingContext")) == NULL ) { + return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); + } - if (ads->config.current_time != 0) { - ads->auth.time_offset = ads->config.current_time - time(NULL); - DEBUG(4,("time offset is %d seconds\n", ads->auth.time_offset)); + if ( (*schema_path = talloc_strdup(mem_ctx, schema)) == NULL ) { + return ADS_ERROR(LDAP_NO_MEMORY); } - talloc_destroy(ctx); + ads_msgfree(ads, res); - return ADS_SUCCESS; + return status; } /** @@ -2617,41 +2619,71 @@ BOOL ads_check_sfu_mapping(ADS_STRUCT *ads) BOOL ret = False; TALLOC_CTX *ctx = NULL; const char *gidnumber, *uidnumber, *homedir, *shell, *gecos; + char *schema_path; + ADS_STRUCT *ads_s = ads; + ADS_STATUS status; + + if ( (ctx = talloc_init("ads_check_sfu_mapping")) == NULL ) { + goto done; + } + + /* establish a new ldap tcp session if necessary */ - ctx = talloc_init("ads_check_sfu_mapping"); - if (ctx == NULL) + if ( !ads->ld ) { + if ( (ads_s = ads_init( ads->server.realm, ads->server.workgroup, + ads->server.ldap_server )) == NULL ) + { + goto done; + } + + ads_s->auth.flags = ADS_AUTH_ANON_BIND; + status = ads_connect( ads_s ); + if ( !ADS_ERR_OK(status)) + goto done; + } + + status = ads_schema_path( ads, ctx, &schema_path ); + if ( !ADS_ERR_OK(status) ) { + DEBUG(3,("ads_check_sfu_mapping: Unable to retrieve schema DN!\n")); goto done; + } - gidnumber = ads_get_attrname_by_oid(ads, ctx, ADS_ATTR_SFU_GIDNUMBER_OID); + gidnumber = ads_get_attrname_by_oid(ads_s, schema_path, ctx, ADS_ATTR_SFU_GIDNUMBER_OID); if (gidnumber == NULL) goto done; ads->schema.sfu_gidnumber_attr = SMB_STRDUP(gidnumber); - uidnumber = ads_get_attrname_by_oid(ads, ctx, ADS_ATTR_SFU_UIDNUMBER_OID); + uidnumber = ads_get_attrname_by_oid(ads_s, schema_path, ctx, ADS_ATTR_SFU_UIDNUMBER_OID); if (uidnumber == NULL) goto done; ads->schema.sfu_uidnumber_attr = SMB_STRDUP(uidnumber); - homedir = ads_get_attrname_by_oid(ads, ctx, ADS_ATTR_SFU_HOMEDIR_OID); + homedir = ads_get_attrname_by_oid(ads_s, schema_path, ctx, ADS_ATTR_SFU_HOMEDIR_OID); if (homedir == NULL) goto done; ads->schema.sfu_homedir_attr = SMB_STRDUP(homedir); - shell = ads_get_attrname_by_oid(ads, ctx, ADS_ATTR_SFU_SHELL_OID); + shell = ads_get_attrname_by_oid(ads_s, schema_path, ctx, ADS_ATTR_SFU_SHELL_OID); if (shell == NULL) goto done; ads->schema.sfu_shell_attr = SMB_STRDUP(shell); - gecos = ads_get_attrname_by_oid(ads, ctx, ADS_ATTR_SFU_GECOS_OID); + gecos = ads_get_attrname_by_oid(ads_s, schema_path, ctx, ADS_ATTR_SFU_GECOS_OID); if (gecos == NULL) goto done; ads->schema.sfu_gecos_attr = SMB_STRDUP(gecos); ret = True; done: - if (ctx) + /* free any temporary ads connections */ + if ( ads_s != ads ) { + ads_destroy( &ads_s ); + } + + if (ctx) { talloc_destroy(ctx); - + } + return ret; } @@ -2679,81 +2711,6 @@ ADS_STATUS ads_domain_sid(ADS_STRUCT *ads, DOM_SID *sid) return ADS_SUCCESS; } -/* this is rather complex - we need to find the allternate (netbios) name - for the domain, but there isn't a simple query to do this. Instead - we look for the principle names on the DCs account and find one that has - the right form, then extract the netbios name of the domain from that - - NOTE! better method is this: - -bin/net -Uadministrator%XXXXX ads search '(&(objectclass=crossref)(dnsroot=VNET3.HOME.SAMBA.ORG))' nETBIOSName - -but you need to force the bind path to match the configurationNamingContext from the rootDSE - -*/ -ADS_STATUS ads_workgroup_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char **workgroup) -{ - char *expr; - ADS_STATUS rc; - char **principles; - char *prefix; - int prefix_length; - int i; - void *res; - const char *attrs[] = {"servicePrincipalName", NULL}; - size_t num_principals; - - (*workgroup) = NULL; - - asprintf(&expr, "(&(objectclass=computer)(dnshostname=%s.%s))", - ads->config.ldap_server_name, ads->config.realm); - if (expr == NULL) { - return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); - } - - rc = ads_search(ads, &res, expr, attrs); - free(expr); - - if (!ADS_ERR_OK(rc)) { - return rc; - } - - principles = ads_pull_strings(ads, mem_ctx, res, - "servicePrincipalName", &num_principals); - - ads_msgfree(ads, res); - - if (!principles) { - return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); - } - - asprintf(&prefix, "HOST/%s.%s/", - ads->config.ldap_server_name, - ads->config.realm); - - prefix_length = strlen(prefix); - - for (i=0;principles[i]; i++) { - if (strnequal(principles[i], prefix, prefix_length) && - !strequal(ads->config.realm, principles[i]+prefix_length) && - !strchr(principles[i]+prefix_length, '.')) { - /* found an alternate (short) name for the domain. */ - DEBUG(3,("Found alternate name '%s' for realm '%s'\n", - principles[i]+prefix_length, - ads->config.realm)); - (*workgroup) = talloc_strdup(mem_ctx, principles[i]+prefix_length); - break; - } - } - free(prefix); - - if (!*workgroup) { - return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); - } - - return ADS_SUCCESS; -} - /** * find our site name * @param ads connection to ads server -- cgit From 163d5ead3a058d3f63b5e5a041715d5642784dff Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 12 May 2006 16:38:51 +0000 Subject: r15544: make sure to define NS_PACKETSZ for Bind 4 interfaces (fix build on us4) (This used to be commit 18f2e1a4e19a83afec6573a020f3a913f07d19dc) --- source3/libads/dns.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/dns.c b/source3/libads/dns.c index 7eeb915ecf..d2e263a9d1 100644 --- a/source3/libads/dns.c +++ b/source3/libads/dns.c @@ -47,7 +47,12 @@ # define NS_HFIXEDSZ HFIXEDSZ # else # define NS_HFIXEDSZ sizeof(HEADER) -# endif +# endif /* HFIXEDSZ */ +# ifdef PACKETSZ +# define NS_PACKETSZ PACKETSZ +# else /* 512 is usually the default */ +# define NS_PACKETSZ 512 +# endif /* PACKETSZ */ # define T_SRV 33 #endif -- cgit From bae13fd8c834f79cf42faae0bc963ac96d505baf Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 12 May 2006 23:20:39 +0000 Subject: r15558: Do not wait endless for a CLDAP reply when the LDAP server is unavailable; use "ldap timeout" handling. Jerry, please check. Guenther (This used to be commit 821bbb4566c4b3f9798054ed3bf772db0c9ae3f2) --- source3/libads/cldap.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/cldap.c b/source3/libads/cldap.c index 6a62f573c9..775d43dc3f 100644 --- a/source3/libads/cldap.c +++ b/source3/libads/cldap.c @@ -165,7 +165,17 @@ static int send_cldap_netlogon(int sock, const char *domain, return 0; } - +static SIG_ATOMIC_T gotalarm; + +/*************************************************************** + Signal function to tell us we timed out. +****************************************************************/ + +static void gotalarm_sig(void) +{ + gotalarm = 1; +} + /* receive a cldap netlogon reply */ @@ -180,8 +190,18 @@ static int recv_cldap_netlogon(int sock, struct cldap_netlogon_reply *reply) blob = data_blob(NULL, 8192); + /* Setup timeout */ + gotalarm = 0; + CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig); + alarm(lp_ldap_timeout()); + /* End setup timeout. */ + ret = read(sock, blob.data, blob.length); + /* Teardown timeout. */ + CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN); + alarm(0); + if (ret <= 0) { d_fprintf(stderr, "no reply received to cldap netlogon\n"); return -1; -- cgit From 453e4b50aae52089eb2c2ae6a2abc3b48425ee55 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sat, 13 May 2006 01:29:04 +0000 Subject: r15559: Smaller fixes for the new cldap code: * replace printf to stderr with DEBUG statements as they get printed in daemons * "net ads lookup" return code Guenther (This used to be commit 8dd925c5fbfcbe711c596d08e8eadc19607d5492) --- source3/libads/cldap.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/cldap.c b/source3/libads/cldap.c index 775d43dc3f..f438f98599 100644 --- a/source3/libads/cldap.c +++ b/source3/libads/cldap.c @@ -66,7 +66,7 @@ static unsigned pull_netlogon_string(char *ret, const char *ptr, uint8 len = (uint8)*(ptr++); if ((pret - ret + len + 1) >= MAX_DNS_LABEL) { - d_fprintf(stderr, "DC returning too long DNS name\n"); + DEBUG(1,("DC returning too long DNS name\n")); return 0; } @@ -151,13 +151,13 @@ static int send_cldap_netlogon(int sock, const char *domain, asn1_pop_tag(&data); if (data.has_error) { - d_fprintf(stderr, "Failed to build cldap netlogon at offset %d\n", (int)data.ofs); + DEBUG(2,("Failed to build cldap netlogon at offset %d\n", (int)data.ofs)); asn1_free(&data); return -1; } if (write(sock, data.data, data.length) != (ssize_t)data.length) { - d_fprintf(stderr, "failed to send cldap query (%s)\n", strerror(errno)); + DEBUG(2,("failed to send cldap query (%s)\n", strerror(errno))); } asn1_free(&data); @@ -203,7 +203,7 @@ static int recv_cldap_netlogon(int sock, struct cldap_netlogon_reply *reply) alarm(0); if (ret <= 0) { - d_fprintf(stderr, "no reply received to cldap netlogon\n"); + DEBUG(1,("no reply received to cldap netlogon\n")); return -1; } blob.length = ret; @@ -225,7 +225,7 @@ static int recv_cldap_netlogon(int sock, struct cldap_netlogon_reply *reply) asn1_end_tag(&data); if (data.has_error) { - d_fprintf(stderr, "Failed to parse cldap reply\n"); + DEBUG(1,("Failed to parse cldap reply\n")); return -1; } -- cgit From f1039b8fb461c6e1276dba8564f62ec1496a7b88 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Sat, 13 May 2006 04:39:19 +0000 Subject: r15560: Since the hotel doesn't have Sci-Fi and no "Doctor Who".... Re-add the capability to specify an OU in which to create the machine account. Done via LDAP prior to the RPC join. (This used to be commit b69ac0e30441faea7a7d677b6bb551aa8ffbf55d) --- source3/libads/ldap.c | 196 +++++++------------------------------------------- 1 file changed, 25 insertions(+), 171 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 6f698dc3a9..63056645cd 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -980,6 +980,7 @@ ADS_STATUS ads_mod_strlist(TALLOC_CTX *ctx, ADS_MODLIST *mods, name, (const void **) vals); } +#if 0 /** * Add a single ber-encoded value to a mod list * @param ctx An initialized TALLOC_CTX @@ -1000,6 +1001,7 @@ static ADS_STATUS ads_mod_ber(TALLOC_CTX *ctx, ADS_MODLIST *mods, return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE|LDAP_MOD_BVALUES, name, (const void **) values); } +#endif /** * Perform an ldap modify @@ -1421,105 +1423,33 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n * @return 0 upon success, or non-zero otherwise **/ -static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *machine_name, - uint32 account_type, - const char *org_unit) +ADS_STATUS ads_create_machine_acct(ADS_STRUCT *ads, const char *machine_name, + const char *org_unit) { - ADS_STATUS ret, status; - char *host_spn, *host_upn, *new_dn, *samAccountName, *controlstr; + ADS_STATUS ret; + char *samAccountName, *controlstr; TALLOC_CTX *ctx; ADS_MODLIST mods; + char *new_dn; const char *objectClass[] = {"top", "person", "organizationalPerson", "user", "computer", NULL}; - const char *servicePrincipalName[7] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL}; - char *psp, *psp2, *psp3, *psp4; - unsigned acct_control; - unsigned exists=0; - fstring my_fqdn; LDAPMessage *res = NULL; - int i, next_spn; - + uint32 acct_control = ( UF_WORKSTATION_TRUST_ACCOUNT |\ + UF_DONT_EXPIRE_PASSWD |\ + UF_ACCOUNTDISABLE ); + if (!(ctx = talloc_init("ads_add_machine_acct"))) return ADS_ERROR(LDAP_NO_MEMORY); ret = ADS_ERROR(LDAP_NO_MEMORY); + + new_dn = talloc_asprintf(ctx, "cn=%s,%s", machine_name, org_unit); + samAccountName = talloc_asprintf(ctx, "%s$", machine_name); - name_to_fqdn(my_fqdn, machine_name); - - status = ads_find_machine_acct(ads, (void **)(void *)&res, machine_name); - if (ADS_ERR_OK(status) && ads_count_replies(ads, res) == 1) { - char *dn_string = ads_get_dn(ads, res); - if (!dn_string) { - DEBUG(1, ("ads_add_machine_acct: ads_get_dn returned NULL (malloc failure?)\n")); - goto done; - } - new_dn = talloc_strdup(ctx, dn_string); - ads_memfree(ads,dn_string); - DEBUG(0, ("ads_add_machine_acct: Host account for %s already exists - modifying old account\n", - machine_name)); - exists=1; - } else { - char *ou_str = ads_ou_string(ads,org_unit); - if (!ou_str) { - DEBUG(1, ("ads_add_machine_acct: ads_ou_string returned NULL (malloc failure?)\n")); - goto done; - } - new_dn = talloc_asprintf(ctx, "cn=%s,%s,%s", machine_name, ou_str, - ads->config.bind_path); - - SAFE_FREE(ou_str); - } - - if (!new_dn) { - goto done; - } - - if (!(host_spn = talloc_asprintf(ctx, "HOST/%s", machine_name))) - goto done; - if (!(host_upn = talloc_asprintf(ctx, "%s@%s", host_spn, ads->config.realm))) - goto done; - servicePrincipalName[0] = talloc_asprintf(ctx, "HOST/%s", machine_name); - psp = talloc_asprintf(ctx, "HOST/%s.%s", - machine_name, - ads->config.realm); - strlower_m(&psp[5]); - servicePrincipalName[1] = psp; - servicePrincipalName[2] = talloc_asprintf(ctx, "CIFS/%s", machine_name); - psp2 = talloc_asprintf(ctx, "CIFS/%s.%s", - machine_name, - ads->config.realm); - strlower_m(&psp2[5]); - servicePrincipalName[3] = psp2; - - /* Ensure servicePrincipalName[4] and [5] are unique. */ - strlower_m(my_fqdn); - psp3 = talloc_asprintf(ctx, "CIFS/%s", my_fqdn); - strlower_m(&psp3[5]); - - next_spn = 4; - for (i = 0; i < next_spn; i++) { - if (strequal(servicePrincipalName[i], psp3)) - break; - } - if (i == next_spn) { - servicePrincipalName[next_spn++] = psp3; - } - - psp4 = talloc_asprintf(ctx, "HOST/%s", my_fqdn); - strlower_m(&psp4[5]); - for (i = 0; i < next_spn; i++) { - if (strequal(servicePrincipalName[i], psp4)) - break; - } - if (i == next_spn) { - servicePrincipalName[next_spn++] = psp4; - } - - if (!(samAccountName = talloc_asprintf(ctx, "%s$", machine_name))) { + if ( !new_dn || !samAccountName ) { goto done; } - - acct_control = account_type | UF_DONT_EXPIRE_PASSWD; + #ifndef ENCTYPE_ARCFOUR_HMAC acct_control |= UF_USE_DES_KEY_ONLY; #endif @@ -1531,44 +1461,18 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *machine_name if (!(mods = ads_init_mods(ctx))) { goto done; } - - if (!exists) { - ads_mod_str(ctx, &mods, "cn", machine_name); - ads_mod_str(ctx, &mods, "sAMAccountName", samAccountName); - ads_mod_strlist(ctx, &mods, "objectClass", objectClass); - } + + ads_mod_str(ctx, &mods, "cn", machine_name); + ads_mod_str(ctx, &mods, "sAMAccountName", samAccountName); + ads_mod_strlist(ctx, &mods, "objectClass", objectClass); ads_mod_str(ctx, &mods, "userAccountControl", controlstr); - ads_mod_str(ctx, &mods, "dNSHostName", my_fqdn); - ads_mod_str(ctx, &mods, "userPrincipalName", host_upn); - ads_mod_strlist(ctx, &mods, "servicePrincipalName", servicePrincipalName); - ads_mod_str(ctx, &mods, "operatingSystem", "Samba"); - ads_mod_str(ctx, &mods, "operatingSystemVersion", SAMBA_VERSION_STRING); - - if (!exists) { - ret = ads_gen_add(ads, new_dn, mods); - } else { - ret = ads_gen_mod(ads, new_dn, mods); - } - if (!ADS_ERR_OK(ret)) { - goto done; - } + ret = ads_gen_add(ads, new_dn, mods); - /* Do not fail if we can't set security descriptor - * it shouldn't be mandatory and probably we just - * don't have enough rights to do it. - */ - if (!exists) { - status = ads_set_machine_sd(ads, machine_name, new_dn); - - if (!ADS_ERR_OK(status)) { - DEBUG(0, ("Warning: ads_set_machine_sd: %s\n", - ads_errstr(status))); - } - } done: ads_msgfree(ads, res); talloc_destroy(ctx); + return ret; } @@ -1783,58 +1687,6 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) return ldap_count_entries(ads->ld, (LDAPMessage *)res); } -/** - * Join a machine to a realm - * Creates the machine account and sets the machine password - * @param ads connection to ads server - * @param machine name of host to add - * @param org_unit Organizational unit to place machine in - * @return status of join - **/ -ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *machine_name, - uint32 account_type, const char *org_unit) -{ - ADS_STATUS status; - LDAPMessage *res = NULL; - char *machine; - - /* machine name must be lowercase */ - machine = SMB_STRDUP(machine_name); - strlower_m(machine); - - /* - status = ads_find_machine_acct(ads, (void **)&res, machine); - if (ADS_ERR_OK(status) && ads_count_replies(ads, res) == 1) { - DEBUG(0, ("Host account for %s already exists - deleting old account\n", machine)); - status = ads_leave_realm(ads, machine); - if (!ADS_ERR_OK(status)) { - DEBUG(0, ("Failed to delete host '%s' from the '%s' realm.\n", - machine, ads->config.realm)); - return status; - } - } - */ - - status = ads_add_machine_acct(ads, machine, account_type, org_unit); - if (!ADS_ERR_OK(status)) { - DEBUG(0, ("ads_join_realm: ads_add_machine_acct failed (%s): %s\n", machine, ads_errstr(status))); - SAFE_FREE(machine); - return status; - } - - status = ads_find_machine_acct(ads, (void **)(void *)&res, machine); - if (!ADS_ERR_OK(status)) { - DEBUG(0, ("ads_join_realm: Host account test failed for machine %s\n", machine)); - SAFE_FREE(machine); - return status; - } - - SAFE_FREE(machine); - ads_msgfree(ads, res); - - return status; -} - /** * Delete a machine from the realm * @param ads connection to ads server @@ -1895,6 +1747,7 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) return status; } +#if 0 /** * add machine account to existing security descriptor * @param ads connection to ads server @@ -1902,7 +1755,7 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) * @param dn DN of security descriptor * @return status **/ -ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) +static ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) { const char *attrs[] = {"nTSecurityDescriptor", "objectSid", 0}; char *expr = 0; @@ -2016,6 +1869,7 @@ ads_set_sd_error: talloc_destroy(ctx); return ret; } +#endif /** * pull the first entry from a ADS result -- cgit From c290d34985830c343b19cc4ffde33ff3e67272d5 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 16 May 2006 15:14:39 +0000 Subject: r15635: Fix a bogus gcc uninit variable message (This used to be commit 53f7104b4fbb4f59c18458f589e25e7b536642cb) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 63056645cd..5f0e296a04 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2473,7 +2473,7 @@ BOOL ads_check_sfu_mapping(ADS_STRUCT *ads) BOOL ret = False; TALLOC_CTX *ctx = NULL; const char *gidnumber, *uidnumber, *homedir, *shell, *gecos; - char *schema_path; + char *schema_path = NULL; ADS_STRUCT *ads_s = ads; ADS_STATUS status; -- cgit From e129dc40f71e9b10c293d8d3f923c5636597bf6f Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 18 May 2006 15:08:09 +0000 Subject: r15696: Free LDAP search result. Guenther (This used to be commit ec26c355b3ef1d3d809c4fbe911ce6fcef5db955) --- source3/libads/ldap.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 5f0e296a04..b208e58504 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2422,6 +2422,8 @@ ADS_STATUS ads_current_time(ADS_STRUCT *ads) DEBUG(4,("time offset is %d seconds\n", ads->auth.time_offset)); } + ads_msgfree(ads, res); + status = ADS_SUCCESS; done: -- cgit From 39c45ce4f1a0cce9dc23e6d8df3f93bb124a19a0 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 18 May 2006 16:08:28 +0000 Subject: r15697: I take no comments as no objections :) Expand the "winbind nss info" to also take "rfc2307" to support the plain posix attributes LDAP schema from win2k3-r2. This work is based on patches from Howard Wilkinson and Bob Gautier (and closes bug #3345). Guenther (This used to be commit 52423e01dc209ba5abde808a446287714ed11567) --- source3/libads/ads_struct.c | 10 +- source3/libads/ldap.c | 150 -------------------- source3/libads/ldap_schema.c | 329 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 334 insertions(+), 155 deletions(-) create mode 100644 source3/libads/ldap_schema.c (limited to 'source3/libads') diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index 48533c7ffb..e546f2ae8a 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -135,11 +135,11 @@ void ads_destroy(ADS_STRUCT **ads) SAFE_FREE((*ads)->config.bind_path); SAFE_FREE((*ads)->config.ldap_server_name); - SAFE_FREE((*ads)->schema.sfu_uidnumber_attr); - SAFE_FREE((*ads)->schema.sfu_gidnumber_attr); - SAFE_FREE((*ads)->schema.sfu_shell_attr); - SAFE_FREE((*ads)->schema.sfu_homedir_attr); - SAFE_FREE((*ads)->schema.sfu_gecos_attr); + SAFE_FREE((*ads)->schema.posix_uidnumber_attr); + SAFE_FREE((*ads)->schema.posix_gidnumber_attr); + SAFE_FREE((*ads)->schema.posix_shell_attr); + SAFE_FREE((*ads)->schema.posix_homedir_attr); + SAFE_FREE((*ads)->schema.posix_gecos_attr); ZERO_STRUCTP(*ads); diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index b208e58504..4a14527a22 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2322,49 +2322,6 @@ static time_t ads_parse_time(const char *str) return timegm(&tm); } - -const char *ads_get_attrname_by_oid(ADS_STRUCT *ads, const char *schema_path, TALLOC_CTX *mem_ctx, const char * OID) -{ - ADS_STATUS rc; - int count = 0; - void *res = NULL; - char *expr = NULL; - const char *attrs[] = { "lDAPDisplayName", NULL }; - char *result; - - if (ads == NULL || mem_ctx == NULL || OID == NULL) { - goto failed; - } - - expr = talloc_asprintf(mem_ctx, "(attributeId=%s)", OID); - if (expr == NULL) { - goto failed; - } - - rc = ads_do_search_retry(ads, schema_path, LDAP_SCOPE_SUBTREE, - expr, attrs, &res); - if (!ADS_ERR_OK(rc)) { - goto failed; - } - - count = ads_count_replies(ads, res); - if (count == 0 || !res) { - goto failed; - } - - result = ads_pull_string(ads, mem_ctx, res, "lDAPDisplayName"); - ads_msgfree(ads, res); - - return result; - -failed: - DEBUG(0,("ads_get_attrname_by_oid: failed to retrieve name for oid: %s\n", - OID)); - - ads_msgfree(ads, res); - return NULL; -} - /** * Find the servers name and realm - this can be done before authentication * The ldapServiceName field on w2k looks like this: @@ -2436,113 +2393,6 @@ done: return status; } -/********************************************************************* -*********************************************************************/ - -static ADS_STATUS ads_schema_path(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char **schema_path) -{ - ADS_STATUS status; - void *res; - const char *schema; - const char *attrs[] = { "schemaNamingContext", NULL }; - - status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); - if (!ADS_ERR_OK(status)) { - return status; - } - - if ( (schema = ads_pull_string(ads, mem_ctx, res, "schemaNamingContext")) == NULL ) { - return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); - } - - if ( (*schema_path = talloc_strdup(mem_ctx, schema)) == NULL ) { - return ADS_ERROR(LDAP_NO_MEMORY); - } - - ads_msgfree(ads, res); - - return status; -} - -/** - * Check for "Services for Unix"-Schema and load some attributes into the ADS_STRUCT - * @param ads connection to ads server - * @return BOOL status of search (False if one or more attributes couldn't be - * found in Active Directory) - **/ -BOOL ads_check_sfu_mapping(ADS_STRUCT *ads) -{ - BOOL ret = False; - TALLOC_CTX *ctx = NULL; - const char *gidnumber, *uidnumber, *homedir, *shell, *gecos; - char *schema_path = NULL; - ADS_STRUCT *ads_s = ads; - ADS_STATUS status; - - if ( (ctx = talloc_init("ads_check_sfu_mapping")) == NULL ) { - goto done; - } - - /* establish a new ldap tcp session if necessary */ - - if ( !ads->ld ) { - if ( (ads_s = ads_init( ads->server.realm, ads->server.workgroup, - ads->server.ldap_server )) == NULL ) - { - goto done; - } - - ads_s->auth.flags = ADS_AUTH_ANON_BIND; - status = ads_connect( ads_s ); - if ( !ADS_ERR_OK(status)) - goto done; - } - - status = ads_schema_path( ads, ctx, &schema_path ); - if ( !ADS_ERR_OK(status) ) { - DEBUG(3,("ads_check_sfu_mapping: Unable to retrieve schema DN!\n")); - goto done; - } - - gidnumber = ads_get_attrname_by_oid(ads_s, schema_path, ctx, ADS_ATTR_SFU_GIDNUMBER_OID); - if (gidnumber == NULL) - goto done; - ads->schema.sfu_gidnumber_attr = SMB_STRDUP(gidnumber); - - uidnumber = ads_get_attrname_by_oid(ads_s, schema_path, ctx, ADS_ATTR_SFU_UIDNUMBER_OID); - if (uidnumber == NULL) - goto done; - ads->schema.sfu_uidnumber_attr = SMB_STRDUP(uidnumber); - - homedir = ads_get_attrname_by_oid(ads_s, schema_path, ctx, ADS_ATTR_SFU_HOMEDIR_OID); - if (homedir == NULL) - goto done; - ads->schema.sfu_homedir_attr = SMB_STRDUP(homedir); - - shell = ads_get_attrname_by_oid(ads_s, schema_path, ctx, ADS_ATTR_SFU_SHELL_OID); - if (shell == NULL) - goto done; - ads->schema.sfu_shell_attr = SMB_STRDUP(shell); - - gecos = ads_get_attrname_by_oid(ads_s, schema_path, ctx, ADS_ATTR_SFU_GECOS_OID); - if (gecos == NULL) - goto done; - ads->schema.sfu_gecos_attr = SMB_STRDUP(gecos); - - ret = True; -done: - /* free any temporary ads connections */ - if ( ads_s != ads ) { - ads_destroy( &ads_s ); - } - - if (ctx) { - talloc_destroy(ctx); - } - - return ret; -} - /** * find the domain sid for our domain * @param ads connection to ads server diff --git a/source3/libads/ldap_schema.c b/source3/libads/ldap_schema.c new file mode 100644 index 0000000000..a0c735208f --- /dev/null +++ b/source3/libads/ldap_schema.c @@ -0,0 +1,329 @@ +/* + Unix SMB/CIFS implementation. + ads (active directory) utility library + Copyright (C) Guenther Deschner 2005-2006 + Copyright (C) Gerald (Jerry) Carter 2006 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +#ifdef HAVE_LDAP + +ADS_STATUS ads_get_attrnames_by_oids(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, + const char *schema_path, + const char **OIDs, size_t num_OIDs, + char ***OIDs_out, char ***names, size_t *count) +{ + ADS_STATUS status; + void *res = NULL; + LDAPMessage *msg; + char *expr = NULL; + const char *attrs[] = { "lDAPDisplayName", "attributeId", NULL }; + int i = 0, p = 0; + + if (!ads || !mem_ctx || !names || !count || !OIDs || !OIDs_out) { + return ADS_ERROR(LDAP_PARAM_ERROR); + } + + if (num_OIDs == 0 || OIDs[0] == NULL) { + return ADS_ERROR_NT(NT_STATUS_NONE_MAPPED); + } + + if ((expr = talloc_asprintf(mem_ctx, "(|")) == NULL) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + + for (i=0; ischema.posix_uidnumber_attr = NULL; + ads->schema.posix_gidnumber_attr = NULL; + ads->schema.posix_homedir_attr = NULL; + ads->schema.posix_shell_attr = NULL; + ads->schema.posix_gecos_attr = NULL; + + ctx = talloc_init("ads_check_posix_schema_mapping"); + if (ctx == NULL) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + + /* establish a new ldap tcp session if necessary */ + + if (!ads->ld) { + if ((ads_s = ads_init(ads->server.realm, ads->server.workgroup, + ads->server.ldap_server)) == NULL) { + status = ADS_ERROR(LDAP_SERVER_DOWN); + goto done; + } + + ads_s->auth.flags = ADS_AUTH_ANON_BIND; + status = ads_connect(ads_s); + if (!ADS_ERR_OK(status)) { + goto done; + } + } + + status = ads_schema_path(ads, ctx, &schema_path); + if (!ADS_ERR_OK(status)) { + DEBUG(3,("ads_check_posix_mapping: Unable to retrieve schema DN!\n")); + goto done; + } + + if (map_type == WB_POSIX_MAP_SFU) { + status = ads_get_attrnames_by_oids(ads, ctx, schema_path, oids_sfu, + ARRAY_SIZE(oids_sfu), + &oids_out, &names_out, &num_names); + } else { + status = ads_get_attrnames_by_oids(ads, ctx, schema_path, oids_rfc2307, + ARRAY_SIZE(oids_rfc2307), + &oids_out, &names_out, &num_names); + } + + if (!ADS_ERR_OK(status)) { + DEBUG(3,("ads_check_posix_schema_mapping: failed %s\n", + ads_errstr(status))); + goto done; + } + + DEBUG(10,("ads_check_posix_schema_mapping: query succeeded, identified: %s\n", + wb_posix_map_str(map_type))); + + for (i=0; ischema.posix_uidnumber_attr = SMB_STRDUP(names_out[i]); + } + if (strequal(ADS_ATTR_RFC2307_GIDNUMBER_OID, oids_out[i]) || + strequal(ADS_ATTR_SFU_GIDNUMBER_OID, oids_out[i])) { + ads->schema.posix_gidnumber_attr = SMB_STRDUP(names_out[i]); + } + if (strequal(ADS_ATTR_RFC2307_HOMEDIR_OID, oids_out[i]) || + strequal(ADS_ATTR_SFU_HOMEDIR_OID, oids_out[i])) { + ads->schema.posix_homedir_attr = SMB_STRDUP(names_out[i]); + } + if (strequal(ADS_ATTR_RFC2307_SHELL_OID, oids_out[i]) || + strequal(ADS_ATTR_SFU_SHELL_OID, oids_out[i])) { + ads->schema.posix_shell_attr = SMB_STRDUP(names_out[i]); + } + if (strequal(ADS_ATTR_RFC2307_GECOS_OID, oids_out[i]) || + strequal(ADS_ATTR_SFU_GECOS_OID, oids_out[i])) { + ads->schema.posix_gecos_attr = SMB_STRDUP(names_out[i]); + } + } + + talloc_destroy(ctx); + + ADS_ERROR_HAVE_NO_MEMORY(ads->schema.posix_uidnumber_attr); + ADS_ERROR_HAVE_NO_MEMORY(ads->schema.posix_gidnumber_attr); + ADS_ERROR_HAVE_NO_MEMORY(ads->schema.posix_homedir_attr); + ADS_ERROR_HAVE_NO_MEMORY(ads->schema.posix_shell_attr); + ADS_ERROR_HAVE_NO_MEMORY(ads->schema.posix_gecos_attr); + + status = ADS_ERROR(LDAP_SUCCESS); + + ads->schema.map_type = map_type; +done: + /* free any temporary ads connections */ + if (ads_s != ads) { + ads_destroy(&ads_s); + } + if (ctx) { + talloc_destroy(ctx); + } + + return status; +} + +#endif -- cgit From c60e96c392df858dd22d39d27513486c5c18c3d2 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 18 May 2006 19:34:25 +0000 Subject: r15698: An attempt to make the winbind lookup_usergroups() call in security=ads more scalable: The most efficient way is to use the "tokenGroups" attribute which gives the nested group membership. As this attribute can not always be retrieved when binding with the machine account (the only garanteed way to get the tokenGroups I could find is when the machine account is a member of the "Pre Win2k Access" builtin group). Our current fallback when "tokenGroups" failed is looking for all groups where the userdn was in the "member" attribute. This behaves not very well in very large AD domains. The patch first tries the "memberOf" attribute on the user's dn in that case and directly retrieves the group's sids by using the LDAP Extended DN control from the user's object. The way to pass down the control to the ldap search call is rather painfull and probably will be rearranged later on. Successfully tested on win2k sp0, win2k sp4, wink3 sp1 and win2k3 r2. Guenther (This used to be commit 7d766b5505e4099ef7dd4e88bb000ebe38d71bd0) --- source3/libads/ldap.c | 220 ++++++++++++++++++++++++++++++++++++++++---- source3/libads/ldap_utils.c | 39 +++++++- 2 files changed, 238 insertions(+), 21 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 4a14527a22..293163c05e 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -445,21 +445,25 @@ static char **ads_pull_strvals(TALLOC_CTX *ctx, const char **in_vals) * @param cookie The paged results cookie to be returned on subsequent calls * @return status of search **/ -ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, - int scope, const char *expr, - const char **attrs, void **res, - int *count, void **cookie) +ADS_STATUS ads_do_paged_search_args(ADS_STRUCT *ads, const char *bind_path, + int scope, const char *expr, + const char **attrs, void *args, void **res, + int *count, void **cookie) { int rc, i, version; char *utf8_expr, *utf8_path, **search_attrs; - LDAPControl PagedResults, NoReferrals, *controls[3], **rcontrols; + LDAPControl PagedResults, NoReferrals, ExtendedDn, *controls[4], **rcontrols; BerElement *cookie_be = NULL; struct berval *cookie_bv= NULL; + BerElement *extdn_be = NULL; + struct berval *extdn_bv= NULL; + TALLOC_CTX *ctx; + ads_control *external_control = (ads_control *) args; *res = NULL; - if (!(ctx = talloc_init("ads_do_paged_search"))) + if (!(ctx = talloc_init("ads_do_paged_search_args"))) return ADS_ERROR(LDAP_NO_MEMORY); /* 0 means the conversion worked but the result was empty @@ -509,10 +513,47 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, NoReferrals.ldctl_value.bv_len = 0; NoReferrals.ldctl_value.bv_val = CONST_DISCARD(char *, ""); + if (external_control && strequal(external_control->control, ADS_EXTENDED_DN_OID)) { + + ExtendedDn.ldctl_oid = CONST_DISCARD(char *, external_control->control); + ExtendedDn.ldctl_iscritical = (char) external_control->critical; + + /* win2k does not accept a ldctl_value beeing passed in */ + + if (external_control->val != 0) { + + if ((extdn_be = ber_alloc_t(LBER_USE_DER)) == NULL ) { + rc = LDAP_NO_MEMORY; + goto done; + } + + if ((ber_printf(extdn_be, "{i}", (ber_int_t) external_control->val)) == -1) { + rc = LDAP_NO_MEMORY; + goto done; + } + if ((ber_flatten(extdn_be, &extdn_bv)) == -1) { + rc = LDAP_NO_MEMORY; + goto done; + } + + ExtendedDn.ldctl_value.bv_len = extdn_bv->bv_len; + ExtendedDn.ldctl_value.bv_val = extdn_bv->bv_val; + + } else { + ExtendedDn.ldctl_value.bv_len = 0; + ExtendedDn.ldctl_value.bv_val = CONST_DISCARD(char *, ""); + } - controls[0] = &NoReferrals; - controls[1] = &PagedResults; - controls[2] = NULL; + controls[0] = &NoReferrals; + controls[1] = &PagedResults; + controls[2] = &ExtendedDn; + controls[3] = NULL; + + } else { + controls[0] = &NoReferrals; + controls[1] = &PagedResults; + controls[2] = NULL; + } /* we need to disable referrals as the openldap libs don't handle them and paged results at the same time. Using them @@ -533,7 +574,7 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, ber_bvfree(cookie_bv); if (rc) { - DEBUG(3,("ads_do_paged_search: ldap_search_with_timeout(%s) -> %s\n", expr, + DEBUG(3,("ads_do_paged_search_args: ldap_search_with_timeout(%s) -> %s\n", expr, ldap_err2string(rc))); goto done; } @@ -565,12 +606,29 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, done: talloc_destroy(ctx); + + if (extdn_be) { + ber_free(extdn_be, 1); + } + + if (extdn_bv) { + ber_bvfree(extdn_bv); + } + /* if/when we decide to utf8-encode attrs, take out this next line */ str_list_free(&search_attrs); return ADS_ERROR(rc); } +ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, + int scope, const char *expr, + const char **attrs, void **res, + int *count, void **cookie) +{ + return ads_do_paged_search_args(ads, bind_path, scope, expr, attrs, NULL, res, count, cookie); +} + /** * Get all results for a search. This uses ads_do_paged_search() to return @@ -583,16 +641,16 @@ done: * @param res ** which will contain results - free res* with ads_msgfree() * @return status of search **/ -ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, - int scope, const char *expr, - const char **attrs, void **res) +ADS_STATUS ads_do_search_all_args(ADS_STRUCT *ads, const char *bind_path, + int scope, const char *expr, + const char **attrs, void *args, void **res) { void *cookie = NULL; int count = 0; ADS_STATUS status; *res = NULL; - status = ads_do_paged_search(ads, bind_path, scope, expr, attrs, res, + status = ads_do_paged_search_args(ads, bind_path, scope, expr, attrs, args, res, &count, &cookie); if (!ADS_ERR_OK(status)) @@ -604,8 +662,8 @@ ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, ADS_STATUS status2; LDAPMessage *msg, *next; - status2 = ads_do_paged_search(ads, bind_path, scope, expr, - attrs, &res2, &count, &cookie); + status2 = ads_do_paged_search_args(ads, bind_path, scope, expr, + attrs, args, &res2, &count, &cookie); if (!ADS_ERR_OK(status2)) break; @@ -626,6 +684,13 @@ ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, return status; } +ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, + int scope, const char *expr, + const char **attrs, void **res) +{ + return ads_do_search_all_args(ads, bind_path, scope, expr, attrs, NULL, res); +} + /** * Run a function on all results for a search. Uses ads_do_paged_search() and * runs the function as each page is returned, using ads_process_results() @@ -2580,4 +2645,127 @@ ADS_STATUS ads_upn_suffixes(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char **suffixe return status; } +/** + * pull a DOM_SID from an extended dn string + * @param mem_ctx TALLOC_CTX + * @param flags string type of extended_dn + * @param sid pointer to a DOM_SID + * @return boolean inidicating success + **/ +BOOL ads_get_sid_from_extended_dn(TALLOC_CTX *mem_ctx, + const char *dn, + enum ads_extended_dn_flags flags, + DOM_SID *sid) +{ + char *p, *q; + + if (!dn) { + return False; + } + + /* + * ADS_EXTENDED_DN_HEX_STRING: + * ;;CN=gd,OU=berlin,OU=suse,DC=ber,DC=suse,DC=de + * + * ADS_EXTENDED_DN_STRING (only with w2k3): + ;;CN=gd,OU=berlin,OU=suse,DC=ber,DC=suse,DC=de + */ + + p = strchr(dn, ';'); + if (!p) { + return False; + } + + if (strncmp(p, "; Date: Thu, 18 May 2006 20:12:45 +0000 Subject: r15701: change 'net ads leave' to disable the machine account in the domain (since removal implies greater permissions that Windows clients require) (This used to be commit ad1f947625612ef16adb69fc2cfeffc68a9a2e02) --- source3/libads/ldap.c | 184 -------------------------------------------------- 1 file changed, 184 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 293163c05e..3307ad83fe 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1752,190 +1752,6 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) return ldap_count_entries(ads->ld, (LDAPMessage *)res); } -/** - * Delete a machine from the realm - * @param ads connection to ads server - * @param hostname Machine to remove - * @return status of delete - **/ -ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) -{ - ADS_STATUS status; - void *res, *msg; - char *hostnameDN, *host; - int rc; - LDAPControl ldap_control; - LDAPControl * pldap_control[2] = {NULL, NULL}; - - pldap_control[0] = &ldap_control; - memset(&ldap_control, 0, sizeof(LDAPControl)); - ldap_control.ldctl_oid = (char *)LDAP_SERVER_TREE_DELETE_OID; - - /* hostname must be lowercase */ - host = SMB_STRDUP(hostname); - strlower_m(host); - - status = ads_find_machine_acct(ads, &res, host); - if (!ADS_ERR_OK(status)) { - DEBUG(0, ("Host account for %s does not exist.\n", host)); - return status; - } - - msg = ads_first_entry(ads, res); - if (!msg) { - return ADS_ERROR_SYSTEM(ENOENT); - } - - hostnameDN = ads_get_dn(ads, (LDAPMessage *)msg); - - - rc = ldap_delete_ext_s(ads->ld, hostnameDN, pldap_control, NULL); - if (rc) { - DEBUG(3,("ldap_delete_ext_s failed with error code %d\n", rc)); - }else { - DEBUG(3,("ldap_delete_ext_s succeeded with error code %d\n", rc)); - } - - ads_memfree(ads, hostnameDN); - if (rc != LDAP_SUCCESS) { - return ADS_ERROR(rc); - } - - status = ads_find_machine_acct(ads, &res, host); - if (ADS_ERR_OK(status) && ads_count_replies(ads, res) == 1) { - DEBUG(0, ("Failed to remove host account.\n")); - return status; - } - - free(host); - - return status; -} - -#if 0 -/** - * add machine account to existing security descriptor - * @param ads connection to ads server - * @param hostname machine to add - * @param dn DN of security descriptor - * @return status - **/ -static ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) -{ - const char *attrs[] = {"nTSecurityDescriptor", "objectSid", 0}; - char *expr = 0; - size_t sd_size = 0; - struct berval bval = {0, NULL}; - prs_struct ps_wire; - char *escaped_hostname = escape_ldap_string_alloc(hostname); - - LDAPMessage *res = 0; - LDAPMessage *msg = 0; - ADS_MODLIST mods = 0; - - NTSTATUS status; - ADS_STATUS ret; - DOM_SID sid; - SEC_DESC *psd = NULL; - TALLOC_CTX *ctx = NULL; - - /* Avoid segmentation fault in prs_mem_free if - * we have to bail out before prs_init */ - ps_wire.is_dynamic = False; - - if (!ads) { - SAFE_FREE(escaped_hostname); - return ADS_ERROR(LDAP_SERVER_DOWN); - } - - ret = ADS_ERROR(LDAP_SUCCESS); - - if (!escaped_hostname) { - return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); - } - - if (asprintf(&expr, "(samAccountName=%s$)", escaped_hostname) == -1) { - DEBUG(1, ("ads_set_machine_sd: asprintf failed!\n")); - SAFE_FREE(escaped_hostname); - return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); - } - - SAFE_FREE(escaped_hostname); - - ret = ads_search(ads, (void *) &res, expr, attrs); - - SAFE_FREE(expr); - - if (!ADS_ERR_OK(ret)) return ret; - - if ( !(msg = ads_first_entry(ads, res) )) { - ret = ADS_ERROR(LDAP_NO_RESULTS_RETURNED); - goto ads_set_sd_error; - } - - if (!ads_pull_sid(ads, msg, attrs[1], &sid)) { - ret = ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); - goto ads_set_sd_error; - } - - if (!(ctx = talloc_init("sec_io_desc"))) { - ret = ADS_ERROR(LDAP_NO_MEMORY); - goto ads_set_sd_error; - } - - if (!ads_pull_sd(ads, ctx, msg, attrs[0], &psd)) { - ret = ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); - goto ads_set_sd_error; - } - - status = sec_desc_add_sid(ctx, &psd, &sid, SEC_RIGHTS_FULL_CTRL, &sd_size); - - if (!NT_STATUS_IS_OK(status)) { - ret = ADS_ERROR_NT(status); - goto ads_set_sd_error; - } - - if (!prs_init(&ps_wire, sd_size, ctx, MARSHALL)) { - ret = ADS_ERROR_NT(NT_STATUS_NO_MEMORY); - } - - if (!sec_io_desc("sd_wire", &psd, &ps_wire, 1)) { - ret = ADS_ERROR(LDAP_NO_MEMORY); - goto ads_set_sd_error; - } - -#if 0 - file_save("/tmp/sec_desc.new", ps_wire.data_p, sd_size); -#endif - if (!(mods = ads_init_mods(ctx))) return ADS_ERROR(LDAP_NO_MEMORY); - - bval.bv_len = prs_offset(&ps_wire); - bval.bv_val = TALLOC(ctx, bval.bv_len); - if (!bval.bv_val) { - ret = ADS_ERROR(LDAP_NO_MEMORY); - goto ads_set_sd_error; - } - - prs_set_offset(&ps_wire, 0); - - if (!prs_copy_data_out(bval.bv_val, &ps_wire, bval.bv_len)) { - ret = ADS_ERROR(LDAP_NO_MEMORY); - goto ads_set_sd_error; - } - - ret = ads_mod_ber(ctx, &mods, attrs[0], &bval); - if (ADS_ERR_OK(ret)) { - ret = ads_gen_mod(ads, dn, mods); - } - -ads_set_sd_error: - ads_msgfree(ads, res); - prs_mem_free(&ps_wire); - talloc_destroy(ctx); - return ret; -} -#endif - /** * pull the first entry from a ADS result * @param ads connection to ads server -- cgit From 1e3147cf12913916cf29ccae1958e79a03a9e327 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 18 May 2006 22:34:16 +0000 Subject: r15704: Prefer LDAP error codes in ads_search_retry_sid(). Guenther (This used to be commit 6cfc65ea20793a72ff1666759bd4e8e446247071) --- source3/libads/ldap_utils.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap_utils.c b/source3/libads/ldap_utils.c index fe0c659b04..c3074233e2 100644 --- a/source3/libads/ldap_utils.c +++ b/source3/libads/ldap_utils.c @@ -154,12 +154,12 @@ ADS_STATUS ads_search_retry_sid(ADS_STRUCT *ads, void **res, sid_string = sid_binstring_hex(sid); if (sid_string == NULL) { - return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + return ADS_ERROR(LDAP_NO_MEMORY); } if (!asprintf(&dn, "", sid_string)) { SAFE_FREE(sid_string); - return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + return ADS_ERROR(LDAP_NO_MEMORY); } status = ads_do_search_retry(ads, dn, LDAP_SCOPE_BASE, -- cgit From ec3021dc3bca5901c70b377c6205c37ce63011df Mon Sep 17 00:00:00 2001 From: Lars Müller Date: Mon, 22 May 2006 20:35:55 +0000 Subject: r15822: Add suggestion made by Ralf Haferkamp. (This used to be commit 7c375fd540fa54ac8ae71c42ed07e01c593044b3) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 3307ad83fe..bac85f3222 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -541,7 +541,7 @@ ADS_STATUS ads_do_paged_search_args(ADS_STRUCT *ads, const char *bind_path, } else { ExtendedDn.ldctl_value.bv_len = 0; - ExtendedDn.ldctl_value.bv_val = CONST_DISCARD(char *, ""); + ExtendedDn.ldctl_value.bv_val = NULL; } controls[0] = &NoReferrals; -- cgit From 2b7b5e9ece6cf81ff2efbdd5b7bc2b2b2baf8e9c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 31 May 2006 10:32:12 +0000 Subject: r15980: Correctly destroy talloc_ctx when the LDAP posix attribute query has failed. Noticed by Bob Gautier. Guenther (This used to be commit 7327f94546a90df25c688dcafd42e0993133057a) --- source3/libads/ldap_schema.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap_schema.c b/source3/libads/ldap_schema.c index a0c735208f..13a8ab0cb0 100644 --- a/source3/libads/ldap_schema.c +++ b/source3/libads/ldap_schema.c @@ -303,13 +303,14 @@ ADS_STATUS ads_check_posix_schema_mapping(ADS_STRUCT *ads, enum wb_posix_mapping } } - talloc_destroy(ctx); - - ADS_ERROR_HAVE_NO_MEMORY(ads->schema.posix_uidnumber_attr); - ADS_ERROR_HAVE_NO_MEMORY(ads->schema.posix_gidnumber_attr); - ADS_ERROR_HAVE_NO_MEMORY(ads->schema.posix_homedir_attr); - ADS_ERROR_HAVE_NO_MEMORY(ads->schema.posix_shell_attr); - ADS_ERROR_HAVE_NO_MEMORY(ads->schema.posix_gecos_attr); + if (!ads->schema.posix_uidnumber_attr || + !ads->schema.posix_gidnumber_attr || + !ads->schema.posix_homedir_attr || + !ads->schema.posix_shell_attr || + !ads->schema.posix_gecos_attr) { + status = ADS_ERROR(LDAP_NO_MEMORY); + goto done; + } status = ADS_ERROR(LDAP_SUCCESS); -- cgit From bf7a5433b4da564c5298e856cdd46383b8998bb2 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 9 Jun 2006 10:50:28 +0000 Subject: r16115: Make "net ads changetrustpw" work again. (adapt to the new UPN/SPN scheme). Guenther (This used to be commit 8fc70d0df0c93c29b49f924bac9ff5d9857cfd9d) --- source3/libads/util.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/util.c b/source3/libads/util.c index 4a4d90d7fb..8e3001ccb0 100644 --- a/source3/libads/util.c +++ b/source3/libads/util.c @@ -26,7 +26,6 @@ ADS_STATUS ads_change_trust_account_password(ADS_STRUCT *ads, char *host_princip { char *password; char *new_password; - char *service_principal; ADS_STATUS ret; uint32 sec_channel_type; @@ -37,9 +36,7 @@ ADS_STATUS ads_change_trust_account_password(ADS_STRUCT *ads, char *host_princip new_password = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH); - asprintf(&service_principal, "HOST/%s", host_principal); - - ret = kerberos_set_password(ads->auth.kdc_server, service_principal, password, service_principal, new_password, ads->auth.time_offset); + ret = kerberos_set_password(ads->auth.kdc_server, host_principal, password, host_principal, new_password, ads->auth.time_offset); if (!ADS_ERR_OK(ret)) { goto failed; @@ -53,14 +50,13 @@ ADS_STATUS ads_change_trust_account_password(ADS_STRUCT *ads, char *host_princip /* Determine if the KDC is salting keys for this principal in a * non-obvious way. */ - if (!kerberos_derive_salting_principal(service_principal)) { - DEBUG(1,("Failed to determine correct salting principal for %s\n", service_principal)); + if (!kerberos_derive_salting_principal(host_principal)) { + DEBUG(1,("Failed to determine correct salting principal for %s\n", host_principal)); ret = ADS_ERROR_SYSTEM(EACCES); goto failed; } failed: - SAFE_FREE(service_principal); SAFE_FREE(password); return ret; } -- cgit From 97f496a0e3e19a8d35f209d6896c2ebc4ccfb9db Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 9 Jun 2006 11:02:52 +0000 Subject: r16117: Make winbindd work again in security=ads. We still used the old HOST/* UPN to get e.g. users, now we need samaccountname$@REA.LM. Guenther (This used to be commit f6516a799aec2db819f79b9a1e641637422a9b4c) --- source3/libads/ldap.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index bac85f3222..7b8b41b10a 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -287,9 +287,13 @@ got_connection: not servicePrincipalName; found by Guenther Deschner @ Sernet. Is this still correct? The comment does not match - the code. --jerry */ + the code. --jerry + + Yes it is :) + - Guenther + */ - asprintf(&ads->auth.user_name, "host/%s", global_myname() ); + asprintf(&ads->auth.user_name, "%s$", global_myname() ); } if (!ads->auth.realm) { -- cgit From 1628d33ba0bb8b6cf7f5253c99b6aebcb304695f Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 13 Jun 2006 13:41:04 +0000 Subject: r16190: Fix more memleaks. Guenther (This used to be commit dfebcc8e19bee06b7c03f88845314e9cfd6f398a) --- source3/libads/ldap.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 7b8b41b10a..7fb5dac51b 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1213,9 +1213,10 @@ char *ads_default_ou_string(ADS_STRUCT *ads, const char *wknguid) status = ads_search_dn(ads, &res, base, attrs); if (!ADS_ERR_OK(status)) { DEBUG(1,("Failed while searching for: %s\n", base)); + SAFE_FREE(base); return NULL; } - free(base); + SAFE_FREE(base); if (ads_count_replies(ads, res) != 1) { return NULL; @@ -1242,6 +1243,10 @@ char *ads_default_ou_string(ADS_STRUCT *ads, const char *wknguid) free(s); } + ads_memfree(ads, wkn_dn); + ldap_value_free(wkn_dn_exp); + ldap_value_free(bind_dn_exp); + return ret; } -- cgit From c0e4753cfcbece7aaf2a96726146b225c9925932 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 13 Jun 2006 18:09:04 +0000 Subject: r16199: Fix Klocwork #1 - ensure we test the first strtok for NULL. Jeremy. (This used to be commit 98751e8190317416de56b4a19a489c5f4b7d6bc9) --- source3/libads/ads_struct.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index e546f2ae8a..7a03a2a80f 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -48,16 +48,18 @@ char *ads_build_path(const char *realm, const char *sep, const char *field, int strlcpy(ret,field, len); p=strtok(r,sep); - strlcat(ret, p, len); - - while ((p=strtok(NULL,sep))) { - char *s; - if (reverse) - asprintf(&s, "%s%s,%s", field, p, ret); - else - asprintf(&s, "%s,%s%s", ret, field, p); - free(ret); - ret = s; + if (p) { + strlcat(ret, p, len); + + while ((p=strtok(NULL,sep))) { + char *s; + if (reverse) + asprintf(&s, "%s%s,%s", field, p, ret); + else + asprintf(&s, "%s,%s%s", ret, field, p); + free(ret); + ret = s; + } } free(r); -- cgit From edcffcbe2875d749e97ddc6a685995973c09808e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 13 Jun 2006 18:09:37 +0000 Subject: r16201: Fix Klocwork 439 (This used to be commit b369d0891afe8b777b837eaac317131232568ca7) --- source3/libads/krb5_setpw.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 254ca7b2a3..ec2ff5afb1 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -528,7 +528,6 @@ ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ, DEBUG(1,("Failed to parse kadmin/changepw (%s)\n", error_message(ret))); return ADS_ERROR_KRB5(ret); } - free(princ_name); /* parse the principal we got as a function argument */ ret = smb_krb5_parse_name(context, princ, &principal); @@ -537,9 +536,12 @@ ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ, krb5_free_principal(context, creds.server); krb5_free_context(context); DEBUG(1,("Failed to parse %s (%s)\n", princ_name, error_message(ret))); + free(princ_name); return ADS_ERROR_KRB5(ret); } + free(princ_name); + /* The creds.server principal takes ownership of this memory. Remember to set back to original value before freeing. */ orig_realm = *krb5_princ_realm(context, creds.server); -- cgit From e030a9e9dcda36edee475aa9fd8772f9f74b3552 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 15 Jun 2006 21:25:57 +0000 Subject: r16268: Add TCP fallback for our implementation of the CHANGEPW kpasswd calls. This patch is mainly based on the work of Todd Stecher and has been reviewed by Jeremy. I sucessfully tested and valgrinded it with MIT 1.4.3, 1.3.5, Heimdal 0.7.2 and 0.6.1rc3. Guenther (This used to be commit 535d03cbe8b021e9aa6d74b62d81b867c494c957) --- source3/libads/krb5_setpw.c | 270 +++++++++++++++++++++++++++----------------- 1 file changed, 166 insertions(+), 104 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index ec2ff5afb1..07e6320c26 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -45,6 +45,14 @@ #define KRB5_KPASSWD_BAD_PRINCIPAL 9 #define KRB5_KPASSWD_ETYPE_NOSUPP 10 +/* + * we've got to be able to distinguish KRB_ERRORs from other + * requests - valid response for CHPW v2 replies. + */ + +#define krb5_is_krb_error(packet) \ + ( packet && packet->length && (((char *)packet->data)[0] == 0x7e || ((char *)packet->data)[0] == 0x5e)) + /* This implements kerberos password change protocol as specified in * kerb-chg-password-02.txt and kerberos-set-passwd-02.txt * as well as microsoft version of the protocol @@ -129,14 +137,16 @@ static krb5_error_code build_kpasswd_request(uint16 pversion, krb5_data *ap_req, const char *princ, const char *passwd, + BOOL use_tcp, krb5_data *packet) { krb5_error_code ret; krb5_data cipherpw; krb5_data encoded_setpw; krb5_replay_data replay; - char *p; + char *p, *msg_start; DATA_BLOB setpw; + unsigned int msg_length; ret = krb5_auth_con_setflags(context, auth_context,KRB5_AUTH_CONTEXT_DO_SEQUENCE); @@ -172,12 +182,16 @@ static krb5_error_code build_kpasswd_request(uint16 pversion, return ret; } - packet->data = (char *)SMB_MALLOC(ap_req->length + cipherpw.length + 6); + packet->data = (char *)SMB_MALLOC(ap_req->length + cipherpw.length + (use_tcp ? 10 : 6 )); if (!packet->data) return -1; + + /* see the RFC for details */ - p = ((char *)packet->data) + 2; + + msg_start = p = ((char *)packet->data) + (use_tcp ? 4 : 0); + p += 2; RSSVAL(p, 0, pversion); p += 2; RSSVAL(p, 0, ap_req->length); @@ -187,7 +201,12 @@ static krb5_error_code build_kpasswd_request(uint16 pversion, memcpy(p, cipherpw.data, cipherpw.length); p += cipherpw.length; packet->length = PTR_DIFF(p,packet->data); - RSSVAL(packet->data, 0, packet->length); + msg_length = PTR_DIFF(p,msg_start); + + if (use_tcp) { + RSIVAL(packet->data, 0, msg_length); + } + RSSVAL(msg_start, 0, msg_length); free(cipherpw.data); /* from 'krb5_mk_priv(...)' */ @@ -248,7 +267,8 @@ static krb5_error_code setpw_result_code_string(krb5_context context, return KRB5KRB_ERR_GENERIC; } } -static krb5_error_code parse_setpw_reply(krb5_context context, +static krb5_error_code parse_setpw_reply(krb5_context context, + BOOL use_tcp, krb5_auth_context auth_context, krb5_data *packet) { @@ -259,23 +279,41 @@ static krb5_error_code parse_setpw_reply(krb5_context context, krb5_data clearresult; krb5_ap_rep_enc_part *ap_rep_enc; krb5_replay_data replay; - - if (packet->length < 4) { + unsigned int msg_length = packet->length; + + + if (packet->length < (use_tcp ? 8 : 4)) { return KRB5KRB_AP_ERR_MODIFIED; } p = packet->data; + /* + ** see if it is an error + */ + if (krb5_is_krb_error(packet)) { + + ret = handle_krberror_packet(context, packet); + if (ret) { + return ret; + } + } + - if (((char *)packet->data)[0] == 0x7e || ((char *)packet->data)[0] == 0x5e) { - /* it's an error packet. We should parse it ... */ - DEBUG(1,("Got error packet 0x%x from kpasswd server\n", - ((char *)packet->data)[0])); - return KRB5KRB_AP_ERR_MODIFIED; + /* tcp... */ + if (use_tcp) { + msg_length -= 4; + if (RIVAL(p, 0) != msg_length) { + DEBUG(1,("Bad TCP packet length (%d/%d) from kpasswd server\n", + RIVAL(p, 0), msg_length)); + return KRB5KRB_AP_ERR_MODIFIED; + } + + p += 4; } - if (RSVAL(p, 0) != packet->length) { + if (RSVAL(p, 0) != msg_length) { DEBUG(1,("Bad packet length (%d/%d) from kpasswd server\n", - RSVAL(p, 0), packet->length)); + RSVAL(p, 0), msg_length)); return KRB5KRB_AP_ERR_MODIFIED; } @@ -342,9 +380,9 @@ static krb5_error_code parse_setpw_reply(krb5_context context, return KRB5KRB_AP_ERR_MODIFIED; } - if(res_code == KRB5_KPASSWD_SUCCESS) - return 0; - else { + if (res_code == KRB5_KPASSWD_SUCCESS) { + return 0; + } else { const char *errstr; setpw_result_code_string(context, res_code, &errstr); DEBUG(1, ("Error changing password: %s (%d)\n", errstr, res_code)); @@ -365,7 +403,10 @@ static ADS_STATUS do_krb5_kpasswd_request(krb5_context context, int ret, sock; socklen_t addr_len; struct sockaddr remote_addr, local_addr; + struct in_addr *addr = interpret_addr2(kdc_host); krb5_address local_kaddr, remote_kaddr; + BOOL use_tcp = False; + ret = krb5_mk_req_extended(context, &auth_context, AP_OPTS_USE_SUBKEY, NULL, credsp, &ap_req); @@ -373,102 +414,123 @@ static ADS_STATUS do_krb5_kpasswd_request(krb5_context context, DEBUG(1,("krb5_mk_req_extended failed (%s)\n", error_message(ret))); return ADS_ERROR_KRB5(ret); } - - sock = open_udp_socket(kdc_host, DEFAULT_KPASSWD_PORT); - if (sock == -1) { - int rc = errno; - free(ap_req.data); - krb5_auth_con_free(context, auth_context); - DEBUG(1,("failed to open kpasswd socket to %s (%s)\n", - kdc_host, strerror(errno))); - return ADS_ERROR_SYSTEM(rc); - } - - addr_len = sizeof(remote_addr); - getpeername(sock, &remote_addr, &addr_len); - addr_len = sizeof(local_addr); - getsockname(sock, &local_addr, &addr_len); - - setup_kaddr(&remote_kaddr, &remote_addr); - setup_kaddr(&local_kaddr, &local_addr); - - ret = krb5_auth_con_setaddrs(context, auth_context, &local_kaddr, NULL); - if (ret) { - close(sock); - free(ap_req.data); - krb5_auth_con_free(context, auth_context); - DEBUG(1,("krb5_auth_con_setaddrs failed (%s)\n", error_message(ret))); - return ADS_ERROR_KRB5(ret); - } - - ret = build_kpasswd_request(pversion, context, auth_context, &ap_req, - princ, newpw, &chpw_req); - if (ret) { - close(sock); - free(ap_req.data); - krb5_auth_con_free(context, auth_context); - DEBUG(1,("build_setpw_request failed (%s)\n", error_message(ret))); - return ADS_ERROR_KRB5(ret); - } - if (write(sock, chpw_req.data, chpw_req.length) != chpw_req.length) { - close(sock); - free(chpw_req.data); - free(ap_req.data); - krb5_auth_con_free(context, auth_context); - DEBUG(1,("send of chpw failed (%s)\n", strerror(errno))); - return ADS_ERROR_SYSTEM(errno); - } + do { - free(chpw_req.data); + if (!use_tcp) { - chpw_rep.length = 1500; - chpw_rep.data = (char *) SMB_MALLOC(chpw_rep.length); - if (!chpw_rep.data) { - close(sock); - free(ap_req.data); - krb5_auth_con_free(context, auth_context); - DEBUG(1,("send of chpw failed (%s)\n", strerror(errno))); - errno = ENOMEM; - return ADS_ERROR_SYSTEM(errno); - } + sock = open_udp_socket(kdc_host, DEFAULT_KPASSWD_PORT); - ret = read(sock, chpw_rep.data, chpw_rep.length); - if (ret < 0) { - close(sock); - free(chpw_rep.data); - free(ap_req.data); - krb5_auth_con_free(context, auth_context); - DEBUG(1,("recv of chpw reply failed (%s)\n", strerror(errno))); - return ADS_ERROR_SYSTEM(errno); - } + } else { - close(sock); - chpw_rep.length = ret; + sock = open_socket_out(SOCK_STREAM, addr, DEFAULT_KPASSWD_PORT, + LONG_CONNECT_TIMEOUT); + } - ret = krb5_auth_con_setaddrs(context, auth_context, NULL,&remote_kaddr); - if (ret) { - free(chpw_rep.data); - free(ap_req.data); - krb5_auth_con_free(context, auth_context); - DEBUG(1,("krb5_auth_con_setaddrs on reply failed (%s)\n", - error_message(ret))); - return ADS_ERROR_KRB5(ret); - } + if (sock == -1) { + int rc = errno; + SAFE_FREE(ap_req.data); + krb5_auth_con_free(context, auth_context); + DEBUG(1,("failed to open kpasswd socket to %s (%s)\n", + kdc_host, strerror(errno))); + return ADS_ERROR_SYSTEM(rc); + } + + addr_len = sizeof(remote_addr); + getpeername(sock, &remote_addr, &addr_len); + addr_len = sizeof(local_addr); + getsockname(sock, &local_addr, &addr_len); + + setup_kaddr(&remote_kaddr, &remote_addr); + setup_kaddr(&local_kaddr, &local_addr); + + ret = krb5_auth_con_setaddrs(context, auth_context, &local_kaddr, NULL); + if (ret) { + close(sock); + SAFE_FREE(ap_req.data); + krb5_auth_con_free(context, auth_context); + DEBUG(1,("krb5_auth_con_setaddrs failed (%s)\n", error_message(ret))); + return ADS_ERROR_KRB5(ret); + } + + ret = build_kpasswd_request(pversion, context, auth_context, &ap_req, + princ, newpw, use_tcp, &chpw_req); + if (ret) { + close(sock); + SAFE_FREE(ap_req.data); + krb5_auth_con_free(context, auth_context); + DEBUG(1,("build_setpw_request failed (%s)\n", error_message(ret))); + return ADS_ERROR_KRB5(ret); + } - ret = parse_setpw_reply(context, auth_context, &chpw_rep); - free(chpw_rep.data); + ret = write(sock, chpw_req.data, chpw_req.length); - if (ret) { - free(ap_req.data); + if (ret != chpw_req.length) { + close(sock); + SAFE_FREE(chpw_req.data); + SAFE_FREE(ap_req.data); + krb5_auth_con_free(context, auth_context); + DEBUG(1,("send of chpw failed (%s)\n", strerror(errno))); + return ADS_ERROR_SYSTEM(errno); + } + + SAFE_FREE(chpw_req.data); + + chpw_rep.length = 1500; + chpw_rep.data = (char *) SMB_MALLOC(chpw_rep.length); + if (!chpw_rep.data) { + close(sock); + SAFE_FREE(ap_req.data); + krb5_auth_con_free(context, auth_context); + DEBUG(1,("send of chpw failed (%s)\n", strerror(errno))); + errno = ENOMEM; + return ADS_ERROR_SYSTEM(errno); + } + + ret = read(sock, chpw_rep.data, chpw_rep.length); + if (ret < 0) { + close(sock); + SAFE_FREE(chpw_rep.data); + SAFE_FREE(ap_req.data); + krb5_auth_con_free(context, auth_context); + DEBUG(1,("recv of chpw reply failed (%s)\n", strerror(errno))); + return ADS_ERROR_SYSTEM(errno); + } + + close(sock); + chpw_rep.length = ret; + + ret = krb5_auth_con_setaddrs(context, auth_context, NULL,&remote_kaddr); + if (ret) { + SAFE_FREE(chpw_rep.data); + SAFE_FREE(ap_req.data); + krb5_auth_con_free(context, auth_context); + DEBUG(1,("krb5_auth_con_setaddrs on reply failed (%s)\n", + error_message(ret))); + return ADS_ERROR_KRB5(ret); + } + + ret = parse_setpw_reply(context, use_tcp, auth_context, &chpw_rep); + SAFE_FREE(chpw_rep.data); + + if (ret) { + + if (ret == KRB5KRB_ERR_RESPONSE_TOO_BIG && !use_tcp) { + DEBUG(5, ("Trying setpw with TCP!!!\n")); + use_tcp = True; + continue; + } + + SAFE_FREE(ap_req.data); + krb5_auth_con_free(context, auth_context); + DEBUG(1,("parse_setpw_reply failed (%s)\n", + error_message(ret))); + return ADS_ERROR_KRB5(ret); + } + + SAFE_FREE(ap_req.data); krb5_auth_con_free(context, auth_context); - DEBUG(1,("parse_setpw_reply failed (%s)\n", - error_message(ret))); - return ADS_ERROR_KRB5(ret); - } - - free(ap_req.data); - krb5_auth_con_free(context, auth_context); + } while ( ret ); return ADS_SUCCESS; } -- cgit From d4ad11ccd8dd6780e048849784b33fd55d5a04b6 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 15 Jun 2006 21:59:25 +0000 Subject: r16272: Fix memleak. Guenther (This used to be commit afdb1189029e01a132f16fea48624126ec65cd77) --- source3/libads/kerberos.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 2dfdc31dd5..90650e1dce 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -195,6 +195,7 @@ int ads_kinit_password(ADS_STRUCT *ads) } if (!ads->auth.password) { + SAFE_FREE(s); return KRB5_LIBOS_CANTREADPWD; } @@ -205,7 +206,7 @@ int ads_kinit_password(ADS_STRUCT *ads) DEBUG(0,("kerberos_kinit_password %s failed: %s\n", s, error_message(ret))); } - free(s); + SAFE_FREE(s); return ret; } -- cgit From be6fd7643659406b6df986e1a96f7e9b87abfe20 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 16 Jun 2006 23:14:12 +0000 Subject: r16322: Klocwork #481., Don't deref null on malloc fail. Jeremy. (This used to be commit dd31f3fc0e044fdae139aefcb21773249c30eb74) --- source3/libads/ldap.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 7fb5dac51b..be15643ba2 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1956,8 +1956,10 @@ char **ads_pull_strings_range(ADS_STRUCT *ads, return NULL; } - memcpy(&strings[*num_strings], new_strings, - sizeof(*new_strings) * num_new_strings); + if (new_strings && num_new_strings) { + memcpy(&strings[*num_strings], new_strings, + sizeof(*new_strings) * num_new_strings); + } (*num_strings) += num_new_strings; -- cgit From d730df0493ee8135cc2315aab3ffb1a0d3b5660a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 16 Jun 2006 23:21:36 +0000 Subject: r16324: Klocwork #499. Allways check results from alloc. Jeremy. (This used to be commit 2b69d436da7b2902ea419f3bcc45c7b5a5c571fb) --- source3/libads/ldap.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index be15643ba2..13459ba40d 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1430,16 +1430,28 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n if (!(host_spn = talloc_asprintf(ctx, "HOST/%s", my_fqdn))) { talloc_destroy(ctx); ads_msgfree(ads, res); - return ADS_ERROR(LDAP_NO_SUCH_OBJECT); + return ADS_ERROR(LDAP_NO_MEMORY); } /* Add the extra principal */ psp1 = talloc_asprintf(ctx, "%s/%s", spn, machine_name); + if (!psp1) { + talloc_destroy(ctx); + ads_msgfree(ads, res); + return ADS_ERROR(LDAP_NO_MEMORY); + } + strupper_m(psp1); strlower_m(&psp1[strlen(spn)]); DEBUG(5,("ads_add_service_principal_name: INFO: Adding %s to host %s\n", psp1, machine_name)); servicePrincipalName[0] = psp1; psp2 = talloc_asprintf(ctx, "%s/%s.%s", spn, machine_name, ads->config.realm); + if (!psp2) { + talloc_destroy(ctx); + ads_msgfree(ads, res); + return ADS_ERROR(LDAP_NO_MEMORY); + } + strupper_m(psp2); strlower_m(&psp2[strlen(spn)]); DEBUG(5,("ads_add_service_principal_name: INFO: Adding %s to host %s\n", psp2, machine_name)); @@ -1449,6 +1461,12 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n * the KDC doesn't send "server principal unknown" errors to clients * which use the DNS name in determining service principal names. */ psp3 = talloc_asprintf(ctx, "%s/%s", spn, my_fqdn); + if (!psp3) { + talloc_destroy(ctx); + ads_msgfree(ads, res); + return ADS_ERROR(LDAP_NO_MEMORY); + } + strupper_m(psp3); strlower_m(&psp3[strlen(spn)]); if (strcmp(psp2, psp3) != 0) { -- cgit From 86a13b97e418a9b06dace463b296f22600ed8b2c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 16 Jun 2006 23:26:48 +0000 Subject: r16326: Klocwork #509. Always check return allocs. Jeremy. (This used to be commit 7e397b534a5ca5809facf5aa84acbfb0b8c9a5b4) --- source3/libads/ldap_printer.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index d6ac09d22b..12bf6eec1d 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -119,6 +119,9 @@ static BOOL map_dword(TALLOC_CTX *ctx, ADS_MODLIST *mods, if (value->type != REG_DWORD) return False; str_value = talloc_asprintf(ctx, "%d", *((uint32 *) value->data_p)); + if (!str_value) { + return False; + } status = ads_mod_str(ctx, mods, value->valuename, str_value); return ADS_ERR_OK(status); } @@ -136,6 +139,9 @@ static BOOL map_bool(TALLOC_CTX *ctx, ADS_MODLIST *mods, return False; str_value = talloc_asprintf(ctx, "%s", *(value->data_p) ? "TRUE" : "FALSE"); + if (!str_value) { + return False; + } status = ads_mod_str(ctx, mods, value->valuename, str_value); return ADS_ERR_OK(status); } @@ -162,6 +168,9 @@ static BOOL map_multi_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods, if (num_vals) { str_values = TALLOC_ARRAY(ctx, char *, num_vals + 1); + if (!str_values) { + return False; + } memset(str_values, '\0', (num_vals + 1) * sizeof(char *)); -- cgit From 8961048d2450e01fd44d33d2c514775b071064e0 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 18 Jun 2006 09:45:18 +0000 Subject: r16339: Fix Klocwork ID 277 278 (cmd_*) 485 487 488 (ldap.c) Volker (This used to be commit 5b1eba76b3ec5cb9b896a9a5641b4d83bdbdd4cf) --- source3/libads/ldap.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 13459ba40d..397d8c02f0 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -904,7 +904,13 @@ char *ads_get_dn_canonical(ADS_STRUCT *ads, void *msg) **/ char *ads_parent_dn(const char *dn) { - char *p = strchr(dn, ','); + char *p; + + if (dn == NULL) { + return NULL; + } + + p = strchr(dn, ','); if (p == NULL) { return NULL; -- cgit From 1b12b48a093147036e85c2fd48eda0d0fb55f385 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 21 Jun 2006 23:43:33 +0000 Subject: r16452: Fix memleak in the CLDAP processing (found by valgrind). Guenther (This used to be commit 479dec68459df606ff566ac86eb3b4bbbd2ca77a) --- source3/libads/cldap.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/cldap.c b/source3/libads/cldap.c index f438f98599..11c083a56a 100644 --- a/source3/libads/cldap.c +++ b/source3/libads/cldap.c @@ -225,6 +225,7 @@ static int recv_cldap_netlogon(int sock, struct cldap_netlogon_reply *reply) asn1_end_tag(&data); if (data.has_error) { + asn1_free(&data); DEBUG(1,("Failed to parse cldap reply\n")); return -1; } @@ -262,6 +263,8 @@ static int recv_cldap_netlogon(int sock, struct cldap_netlogon_reply *reply) data_blob_free(&os3); data_blob_free(&blob); + asn1_free(&data); + return 0; } -- cgit From 49f6498a6f4efca5097e6338b14bcfe07a8261df Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 28 Jun 2006 01:21:54 +0000 Subject: r16589: Fix Klocwork #1999. Although it should be impossible to get duplicate OID's returned in the oids_out list it is still good programming practice to clear out a malloc'ed string before re-writing it (especially in a loop). Jeremy (This used to be commit ae02c05bfca46eb6a8ba25b124c18a358a759cb5) --- source3/libads/ldap_schema.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap_schema.c b/source3/libads/ldap_schema.c index 13a8ab0cb0..b65ff956ac 100644 --- a/source3/libads/ldap_schema.c +++ b/source3/libads/ldap_schema.c @@ -283,22 +283,27 @@ ADS_STATUS ads_check_posix_schema_mapping(ADS_STRUCT *ads, enum wb_posix_mapping if (strequal(ADS_ATTR_RFC2307_UIDNUMBER_OID, oids_out[i]) || strequal(ADS_ATTR_SFU_UIDNUMBER_OID, oids_out[i])) { + SAFE_FREE(ads->schema.posix_uidnumber_attr); ads->schema.posix_uidnumber_attr = SMB_STRDUP(names_out[i]); } if (strequal(ADS_ATTR_RFC2307_GIDNUMBER_OID, oids_out[i]) || strequal(ADS_ATTR_SFU_GIDNUMBER_OID, oids_out[i])) { + SAFE_FREE(ads->schema.posix_gidnumber_attr); ads->schema.posix_gidnumber_attr = SMB_STRDUP(names_out[i]); } if (strequal(ADS_ATTR_RFC2307_HOMEDIR_OID, oids_out[i]) || strequal(ADS_ATTR_SFU_HOMEDIR_OID, oids_out[i])) { + SAFE_FREE(ads->schema.posix_homedir_attr); ads->schema.posix_homedir_attr = SMB_STRDUP(names_out[i]); } if (strequal(ADS_ATTR_RFC2307_SHELL_OID, oids_out[i]) || strequal(ADS_ATTR_SFU_SHELL_OID, oids_out[i])) { + SAFE_FREE(ads->schema.posix_shell_attr); ads->schema.posix_shell_attr = SMB_STRDUP(names_out[i]); } if (strequal(ADS_ATTR_RFC2307_GECOS_OID, oids_out[i]) || strequal(ADS_ATTR_SFU_GECOS_OID, oids_out[i])) { + SAFE_FREE(ads->schema.posix_gecos_attr); ads->schema.posix_gecos_attr = SMB_STRDUP(names_out[i]); } } -- cgit From 8f0ea257b61f435060cfe6995e238c6d4b07de21 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 29 Jun 2006 17:11:14 +0000 Subject: r16685: Fix bug #3901 reported by jason@ncac.gwu.edu. Jeremy. (This used to be commit d48655d9c0b31d15327655140c021de29873d2c5) --- source3/libads/ldap.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 397d8c02f0..db2a51307a 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1408,7 +1408,7 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n ADS_STATUS ret; TALLOC_CTX *ctx; LDAPMessage *res = NULL; - char *host_spn, *psp1, *psp2, *psp3; + char *psp1, *psp2, *psp3; ADS_MODLIST mods; fstring my_fqdn; char *dn_string = NULL; @@ -1433,12 +1433,6 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n name_to_fqdn(my_fqdn, machine_name); strlower_m(my_fqdn); - if (!(host_spn = talloc_asprintf(ctx, "HOST/%s", my_fqdn))) { - talloc_destroy(ctx); - ads_msgfree(ads, res); - return ADS_ERROR(LDAP_NO_MEMORY); - } - /* Add the extra principal */ psp1 = talloc_asprintf(ctx, "%s/%s", spn, machine_name); if (!psp1) { -- cgit From 67d8c7432f116a0721b9bbff38632b8cc0535259 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 6 Jul 2006 13:38:41 +0000 Subject: r16836: When receiving a CLDAP reply make sure that we always store the correct netbios domain name in server affinity cache. Guenther (This used to be commit 08958411eeff430fb523d9b73e0259d060bac17b) --- source3/libads/ldap.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index db2a51307a..ef4be210c6 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -149,18 +149,20 @@ BOOL ads_try_connect(ADS_STRUCT *ads, const char *server ) SAFE_FREE(ads->config.realm); SAFE_FREE(ads->config.bind_path); SAFE_FREE(ads->config.ldap_server_name); + SAFE_FREE(ads->server.workgroup); ads->config.ldap_server_name = SMB_STRDUP(cldap_reply.hostname); strupper_m(cldap_reply.domain); ads->config.realm = SMB_STRDUP(cldap_reply.domain); ads->config.bind_path = ads_build_dn(ads->config.realm); + ads->server.workgroup = SMB_STRDUP(cldap_reply.netbios_domain); ads->ldap_port = LDAP_PORT; ads->ldap_ip = *interpret_addr2(srv); SAFE_FREE(srv); /* cache the successful connection */ - + saf_store( ads->server.workgroup, server ); return True; -- cgit From f3e71c60727366eca0f5023c83c661c36512153d Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 7 Jul 2006 11:43:47 +0000 Subject: r16861: Fixing crash bug when passing no domain/realm name to the CLDAP request. Guenther (This used to be commit 863aeb621afa7dcec1bfef8e503ef8ed363e3742) --- source3/libads/cldap.c | 10 ++++++---- source3/libads/ldap.c | 7 ++++--- 2 files changed, 10 insertions(+), 7 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/cldap.c b/source3/libads/cldap.c index 11c083a56a..f67372805f 100644 --- a/source3/libads/cldap.c +++ b/source3/libads/cldap.c @@ -115,10 +115,12 @@ static int send_cldap_netlogon(int sock, const char *domain, asn1_write_BOOLEAN2(&data, False); asn1_push_tag(&data, ASN1_CONTEXT(0)); - asn1_push_tag(&data, ASN1_CONTEXT(3)); - asn1_write_OctetString(&data, "DnsDomain", 9); - asn1_write_OctetString(&data, domain, strlen(domain)); - asn1_pop_tag(&data); + if (domain) { + asn1_push_tag(&data, ASN1_CONTEXT(3)); + asn1_write_OctetString(&data, "DnsDomain", 9); + asn1_write_OctetString(&data, domain, strlen(domain)); + asn1_pop_tag(&data); + } asn1_push_tag(&data, ASN1_CONTEXT(3)); asn1_write_OctetString(&data, "Host", 4); diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index ef4be210c6..ebffd667eb 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -122,15 +122,16 @@ BOOL ads_try_connect(ADS_STRUCT *ads, const char *server ) return False; } - DEBUG(5,("ads_try_connect: sending CLDAP request to %s\n", server)); + DEBUG(5,("ads_try_connect: sending CLDAP request to %s (realm: %s)\n", + server, ads->config.realm)); /* this copes with inet_ntoa brokenness */ srv = SMB_STRDUP(server); ZERO_STRUCT( cldap_reply ); - - if ( !ads_cldap_netlogon( srv, ads->server.realm, &cldap_reply ) ) { + + if ( !ads_cldap_netlogon( srv, ads->config.realm, &cldap_reply ) ) { DEBUG(3,("ads_try_connect: CLDAP request %s failed.\n", srv)); return False; } -- cgit From 7048040be841c5abb295533ba3c0d70956fce476 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 7 Jul 2006 11:59:19 +0000 Subject: r16862: Reverting accidential changes in ads_try_connect() from previous commit. Guenther (This used to be commit 6257f9af93f2391940b2c60fe39c0bf106de15dd) --- source3/libads/ldap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index ebffd667eb..b017ff941b 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -123,7 +123,7 @@ BOOL ads_try_connect(ADS_STRUCT *ads, const char *server ) } DEBUG(5,("ads_try_connect: sending CLDAP request to %s (realm: %s)\n", - server, ads->config.realm)); + server, ads->server.realm)); /* this copes with inet_ntoa brokenness */ @@ -131,7 +131,7 @@ BOOL ads_try_connect(ADS_STRUCT *ads, const char *server ) ZERO_STRUCT( cldap_reply ); - if ( !ads_cldap_netlogon( srv, ads->config.realm, &cldap_reply ) ) { + if ( !ads_cldap_netlogon( srv, ads->server.realm, &cldap_reply ) ) { DEBUG(3,("ads_try_connect: CLDAP request %s failed.\n", srv)); return False; } -- cgit From fbdcf2663b56007a438ac4f0d8d82436b1bfe688 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 11 Jul 2006 18:01:26 +0000 Subject: r16945: Sync trunk -> 3.0 for 3.0.24 code. Still need to do the upper layer directories but this is what everyone is waiting for.... Jeremy. (This used to be commit 9dafb7f48ca3e7af956b0a7d1720c2546fc4cfb8) --- source3/libads/dns.c | 4 ++++ source3/libads/ldap.c | 9 +++++---- source3/libads/sasl.c | 2 -- 3 files changed, 9 insertions(+), 6 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/dns.c b/source3/libads/dns.c index d2e263a9d1..321b435527 100644 --- a/source3/libads/dns.c +++ b/source3/libads/dns.c @@ -39,8 +39,12 @@ #define MAX_DNS_PACKET_SIZE 0xffff #ifdef NS_HFIXEDSZ /* Bind 8/9 interface */ +#if !defined(C_IN) /* AIX 5.3 already defines C_IN */ # define C_IN ns_c_in +#endif +#if !defined(T_A) /* AIX 5.3 already defines T_A */ # define T_A ns_t_a +#endif # define T_SRV ns_t_srv #else # ifdef HFIXEDSZ diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index b017ff941b..58eca99f9e 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -831,10 +831,11 @@ ADS_STATUS ads_search(ADS_STRUCT *ads, void **res, * @param attrs Attributes to retrieve * @return status of search **/ -ADS_STATUS ads_search_dn(ADS_STRUCT *ads, void **res, +ADS_STATUS ads_search_dn(ADS_STRUCT *ads, void *_res, const char *dn, const char **attrs) { + void **res = (void **)_res; return ads_do_search(ads, dn, LDAP_SCOPE_BASE, "(objectclass=*)", attrs, res); } @@ -973,8 +974,9 @@ ADS_MODLIST ads_init_mods(TALLOC_CTX *ctx) */ static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, int mod_op, const char *name, - const void **invals) + const void *_invals) { + const void **invals = (const void **)_invals; int curmod; LDAPMod **modlist = (LDAPMod **) *mods; struct berval **ber_values = NULL; @@ -1037,8 +1039,7 @@ ADS_STATUS ads_mod_str(TALLOC_CTX *ctx, ADS_MODLIST *mods, if (!val) return ads_modlist_add(ctx, mods, LDAP_MOD_DELETE, name, NULL); - return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE, name, - (const void **) values); + return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE, name, values); } /** diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index a12af43eb3..3c0bea93d6 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -278,7 +278,6 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) uint8 *p; uint32 max_msg_size; char *sname; - unsigned sec_layer; ADS_STATUS status; krb5_principal principal; krb5_context ctx = NULL; @@ -391,7 +390,6 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) file_save("sasl_gssapi.dat", output_token.value, output_token.length); #endif max_msg_size = (p[1]<<16) | (p[2]<<8) | p[3]; - sec_layer = *p; gss_release_buffer(&minor_status, &output_token); -- cgit From 060b155cd2f77e37086f97461f93e9ef1ff8dce2 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 11 Jul 2006 18:45:22 +0000 Subject: r16952: New derive DES salt code and Krb5 keytab generation Major points of interest: * Figure the DES salt based on the domain functional level and UPN (if present and applicable) * Only deal with the DES-CBC-MD5, DES-CBC-CRC, and RC4-HMAC keys * Remove all the case permutations in the keytab entry generation (to be partially re-added only if necessary). * Generate keytab entries based on the existing SPN values in AD The resulting keytab looks like: ktutil: list -e slot KVNO Principal ---- ---- --------------------------------------------------------------------- 1 6 host/suse10.plainjoe.org@COLOR.PLAINJOE.ORG (DES cbc mode with CRC-32) 2 6 host/suse10.plainjoe.org@COLOR.PLAINJOE.ORG (DES cbc mode with RSA-MD5) 3 6 host/suse10.plainjoe.org@COLOR.PLAINJOE.ORG (ArcFour with HMAC/md5) 4 6 host/suse10@COLOR.PLAINJOE.ORG (DES cbc mode with CRC-32) 5 6 host/suse10@COLOR.PLAINJOE.ORG (DES cbc mode with RSA-MD5) 6 6 host/suse10@COLOR.PLAINJOE.ORG (ArcFour with HMAC/md5) 7 6 suse10$@COLOR.PLAINJOE.ORG (DES cbc mode with CRC-32) 8 6 suse10$@COLOR.PLAINJOE.ORG (DES cbc mode with RSA-MD5) 9 6 suse10$@COLOR.PLAINJOE.ORG (ArcFour with HMAC/md5) The list entries are the two basic SPN values (host/NetBIOSName & host/dNSHostName) and the sAMAccountName value. The UPN will be added as well if the machine has one. This fixes 'kinit -k'. Tested keytab using mod_auth_krb and MIT's telnet. ads_verify_ticket() continues to work with RC4-HMAC and DES keys. (This used to be commit 6261dd3c67d10db6cfa2e77a8d304d3dce4050a4) --- source3/libads/kerberos.c | 571 +++++++-------------------------------- source3/libads/kerberos_keytab.c | 391 +++++++++++++++------------ source3/libads/kerberos_verify.c | 14 +- source3/libads/ldap.c | 260 +++++++++++++----- source3/libads/util.c | 8 - 5 files changed, 510 insertions(+), 734 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 90650e1dce..a25daf5399 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -5,6 +5,7 @@ Copyright (C) Remus Koos 2001 Copyright (C) Nalin Dahyabhai 2004. Copyright (C) Jeremy Allison 2004. + Copyright (C) Gerald Carter 2006. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -268,11 +269,89 @@ static char *kerberos_secrets_fetch_salting_principal(const char *service, int e } /************************************************************************ - Routine to get the salting principal for this service. Active - Directory may use a non-obvious principal name to generate the salt - when it determines the key to use for encrypting tickets for a service, - and hopefully we detected that when we joined the domain. - Caller must free if return is not null. + Return the standard DES salt key +************************************************************************/ + +char* kerberos_standard_des_salt( void ) +{ + fstring salt; + + fstr_sprintf( salt, "host/%s.%s@", global_myname(), lp_realm() ); + strlower_m( salt ); + fstrcat( salt, lp_realm() ); + + return SMB_STRDUP( salt ); +} + +/************************************************************************ +************************************************************************/ + +static char* des_salt_key( void ) +{ + char *key; + + asprintf(&key, "%s/DES/%s", SECRETS_SALTING_PRINCIPAL, lp_realm()); + + return key; +} + +/************************************************************************ +************************************************************************/ + +BOOL kerberos_secrets_store_des_salt( const char* salt ) +{ + char* key; + BOOL ret; + + if ( (key = des_salt_key()) == NULL ) { + DEBUG(0,("kerberos_secrets_store_des_salt: failed to generate key!\n")); + return False; + } + + if ( !salt ) { + DEBUG(8,("kerberos_secrets_store_des_salt: deleting salt\n")); + secrets_delete( key ); + } + + DEBUG(3,("kerberos_secrets_store_des_salt: Storing salt \"%s\"\n", salt)); + + ret = secrets_store( key, salt, strlen(salt)+1 ); + + SAFE_FREE( key ); + + return ret; +} + +/************************************************************************ +************************************************************************/ + +char* kerberos_secrets_fetch_des_salt( void ) +{ + char *salt, *key; + + if ( (key = des_salt_key()) == NULL ) { + DEBUG(0,("kerberos_secrets_fetch_des_salt: failed to generate key!\n")); + return False; + } + + if ( !salt ) { + DEBUG(8,("kerberos_secrets_fetch_des_salt: NULL salt!\n")); + secrets_delete( key ); + } + + salt = (char*)secrets_fetch( key, NULL ); + + SAFE_FREE( key ); + + return salt; +} + + +/************************************************************************ + Routine to get the salting principal for this service. This is + maintained for backwards compatibilty with releases prior to 3.0.24. + Since we store the salting principal string only at join, we may have + to look for the older tdb keys. Caller must free if return is not null. ************************************************************************/ krb5_principal kerberos_fetch_salt_princ_for_host_princ(krb5_context context, @@ -281,23 +360,29 @@ krb5_principal kerberos_fetch_salt_princ_for_host_princ(krb5_context context, { char *unparsed_name = NULL, *salt_princ_s = NULL; krb5_principal ret_princ = NULL; + + /* lookup new key first */ - if (smb_krb5_unparse_name(context, host_princ, &unparsed_name) != 0) { - return (krb5_principal)NULL; - } + if ( (salt_princ_s = kerberos_secrets_fetch_des_salt()) == NULL ) { + + /* look under the old key. If this fails, just use the standard key */ - if ((salt_princ_s = kerberos_secrets_fetch_salting_principal(unparsed_name, enctype)) == NULL) { - SAFE_FREE(unparsed_name); - return (krb5_principal)NULL; + if (smb_krb5_unparse_name(context, host_princ, &unparsed_name) != 0) { + return (krb5_principal)NULL; + } + if ((salt_princ_s = kerberos_secrets_fetch_salting_principal(unparsed_name, enctype)) == NULL) { + /* fall back to host/machine.realm@REALM */ + salt_princ_s = kerberos_standard_des_salt(); + } } if (smb_krb5_parse_name(context, salt_princ_s, &ret_princ) != 0) { - SAFE_FREE(unparsed_name); - SAFE_FREE(salt_princ_s); - return (krb5_principal)NULL; + ret_princ = NULL; } + SAFE_FREE(unparsed_name); SAFE_FREE(salt_princ_s); + return ret_princ; } @@ -362,465 +447,9 @@ BOOL kerberos_secrets_store_salting_principal(const char *service, return ret; } -/************************************************************************ - Routine to get initial credentials as a service ticket for the local machine. - Returns a buffer initialized with krb5_mk_req_extended. - ************************************************************************/ - -static krb5_error_code get_service_ticket(krb5_context ctx, - krb5_ccache ccache, - const char *service_principal, - int enctype, - krb5_data *p_outbuf) -{ - krb5_creds creds, *new_creds = NULL; - char *service_s = NULL; - char *machine_account = NULL, *password = NULL; - krb5_data in_data; - krb5_auth_context auth_context = NULL; - krb5_error_code err = 0; - - ZERO_STRUCT(creds); - - asprintf(&machine_account, "%s$@%s", global_myname(), lp_realm()); - if (machine_account == NULL) { - goto out; - } - password = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL); - if (password == NULL) { - goto out; - } - if ((err = kerberos_kinit_password(machine_account, password, - 0, LIBADS_CCACHE_NAME)) != 0) { - DEBUG(0,("get_service_ticket: kerberos_kinit_password %s failed: %s\n", - machine_account, - error_message(err))); - goto out; - } - - /* Ok - the above call has gotten a TGT. Now we need to get a service - ticket to ourselves. */ - - /* Set up the enctype and client and server principal fields for krb5_get_credentials. */ - kerberos_set_creds_enctype(&creds, enctype); - - if ((err = krb5_cc_get_principal(ctx, ccache, &creds.client))) { - DEBUG(3, ("get_service_ticket: krb5_cc_get_principal failed: %s\n", - error_message(err))); - goto out; - } - - if (strchr_m(service_principal, '@')) { - asprintf(&service_s, "%s", service_principal); - } else { - asprintf(&service_s, "%s@%s", service_principal, lp_realm()); - } - - if ((err = smb_krb5_parse_name(ctx, service_s, &creds.server))) { - DEBUG(0,("get_service_ticket: smb_krb5_parse_name %s failed: %s\n", - service_s, error_message(err))); - goto out; - } - - if ((err = krb5_get_credentials(ctx, 0, ccache, &creds, &new_creds))) { - DEBUG(5,("get_service_ticket: krb5_get_credentials for %s enctype %d failed: %s\n", - service_s, enctype, error_message(err))); - goto out; - } - - memset(&in_data, '\0', sizeof(in_data)); - if ((err = krb5_mk_req_extended(ctx, &auth_context, 0, &in_data, - new_creds, p_outbuf)) != 0) { - DEBUG(0,("get_service_ticket: krb5_mk_req_extended failed: %s\n", - error_message(err))); - goto out; - } - - out: - - if (auth_context) { - krb5_auth_con_free(ctx, auth_context); - } - if (new_creds) { - krb5_free_creds(ctx, new_creds); - } - if (creds.server) { - krb5_free_principal(ctx, creds.server); - } - if (creds.client) { - krb5_free_principal(ctx, creds.client); - } - - SAFE_FREE(service_s); - SAFE_FREE(password); - SAFE_FREE(machine_account); - return err; -} - -/************************************************************************ - Check if the machine password can be used in conjunction with the salting_principal - to generate a key which will successfully decrypt the AP_REQ already - gotten as a message to the local machine. - ************************************************************************/ - -static BOOL verify_service_password(krb5_context ctx, - int enctype, - const char *salting_principal, - krb5_data *in_data) -{ - BOOL ret = False; - krb5_principal salting_kprinc = NULL; - krb5_ticket *ticket = NULL; - krb5_keyblock key; - krb5_data passdata; - char *salting_s = NULL; - char *machine_account = NULL, *password = NULL; - krb5_auth_context auth_context = NULL; - krb5_error_code err; - - memset(&passdata, '\0', sizeof(passdata)); - memset(&key, '\0', sizeof(key)); - - asprintf(&machine_account, "%s$@%s", global_myname(), lp_realm()); - if (machine_account == NULL) { - goto out; - } - password = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL); - if (password == NULL) { - goto out; - } - - if (strchr_m(salting_principal, '@')) { - asprintf(&salting_s, "%s", salting_principal); - } else { - asprintf(&salting_s, "%s@%s", salting_principal, lp_realm()); - } - - if ((err = smb_krb5_parse_name(ctx, salting_s, &salting_kprinc))) { - DEBUG(0,("verify_service_password: smb_krb5_parse_name %s failed: %s\n", - salting_s, error_message(err))); - goto out; - } - - passdata.length = strlen(password); - passdata.data = (char*)password; - if ((err = create_kerberos_key_from_string_direct(ctx, salting_kprinc, &passdata, &key, enctype))) { - DEBUG(0,("verify_service_password: create_kerberos_key_from_string %d failed: %s\n", - enctype, error_message(err))); - goto out; - } - - if ((err = krb5_auth_con_init(ctx, &auth_context)) != 0) { - DEBUG(0,("verify_service_password: krb5_auth_con_init failed %s\n", error_message(err))); - goto out; - } - - if ((err = krb5_auth_con_setuseruserkey(ctx, auth_context, &key)) != 0) { - DEBUG(0,("verify_service_password: krb5_auth_con_setuseruserkey failed %s\n", error_message(err))); - goto out; - } - - if (!(err = krb5_rd_req(ctx, &auth_context, in_data, NULL, NULL, NULL, &ticket))) { - DEBUG(10,("verify_service_password: decrypted message with enctype %u salt %s!\n", - (unsigned int)enctype, salting_s)); - ret = True; - } - - out: - - memset(&passdata, 0, sizeof(passdata)); - krb5_free_keyblock_contents(ctx, &key); - if (ticket != NULL) { - krb5_free_ticket(ctx, ticket); - } - if (salting_kprinc) { - krb5_free_principal(ctx, salting_kprinc); - } - SAFE_FREE(salting_s); - SAFE_FREE(password); - SAFE_FREE(machine_account); - return ret; -} - -/************************************************************************ - * - * From the current draft of kerberos-clarifications: - * - * It is not possible to reliably generate a user's key given a pass - * phrase without contacting the KDC, since it will not be known - * whether alternate salt or parameter values are required. - * - * And because our server has a password, we have this exact problem. We - * make multiple guesses as to which principal name provides the salt which - * the KDC is using. - * - ************************************************************************/ - -static void kerberos_derive_salting_principal_for_enctype(const char *service_principal, - krb5_context ctx, - krb5_ccache ccache, - krb5_enctype enctype, - krb5_enctype *enctypes) -{ - char *salting_principals[3] = {NULL, NULL, NULL}, *second_principal = NULL; - krb5_error_code err = 0; - krb5_data outbuf; - int i, j; - - memset(&outbuf, '\0', sizeof(outbuf)); - - /* Check that the service_principal is useful. */ - if ((service_principal == NULL) || (strlen(service_principal) == 0)) { - return; - } - - /* Generate our first guess -- the principal as-given. */ - asprintf(&salting_principals[0], "%s", service_principal); - if ((salting_principals[0] == NULL) || (strlen(salting_principals[0]) == 0)) { - return; - } - - /* Generate our second guess -- the computer's principal, as Win2k3. */ - asprintf(&second_principal, "host/%s.%s", global_myname(), lp_realm()); - if (second_principal != NULL) { - strlower_m(second_principal); - asprintf(&salting_principals[1], "%s@%s", second_principal, lp_realm()); - SAFE_FREE(second_principal); - } - if ((salting_principals[1] == NULL) || (strlen(salting_principals[1]) == 0)) { - goto out; - } - - /* Generate our third guess -- the computer's principal, as Win2k. */ - asprintf(&second_principal, "HOST/%s", global_myname()); - if (second_principal != NULL) { - strlower_m(second_principal + 5); - asprintf(&salting_principals[2], "%s@%s", - second_principal, lp_realm()); - SAFE_FREE(second_principal); - } - if ((salting_principals[2] == NULL) || (strlen(salting_principals[2]) == 0)) { - goto out; - } - - /* Get a service ticket for ourselves into our memory ccache. */ - /* This will commonly fail if there is no principal by that name (and we're trying - many names). So don't print a debug 0 error. */ - - if ((err = get_service_ticket(ctx, ccache, service_principal, enctype, &outbuf)) != 0) { - DEBUG(3, ("verify_service_password: get_service_ticket failed: %s\n", - error_message(err))); - goto out; - } - - /* At this point we have a message to ourselves, salted only the KDC knows how. We - have to work out what that salting is. */ - - /* Try and find the correct salting principal. */ - for (i = 0; i < sizeof(salting_principals) / sizeof(salting_principals[i]); i++) { - if (verify_service_password(ctx, enctype, salting_principals[i], &outbuf)) { - break; - } - } - - /* If we failed to get a match, return. */ - if (i >= sizeof(salting_principals) / sizeof(salting_principals[i])) { - goto out; - } - - /* If we succeeded, store the principal for use for all enctypes which - * share the same cipher and string-to-key function. Doing this here - * allows servers which just pass a keytab to krb5_rd_req() to work - * correctly. */ - for (j = 0; enctypes[j] != 0; j++) { - if (enctype != enctypes[j]) { - /* If this enctype isn't compatible with the one which - * we used, skip it. */ - - if (!kerberos_compatible_enctypes(ctx, enctypes[j], enctype)) - continue; - } - /* If the principal which gives us the proper salt is the one - * which we would normally guess, don't bother noting anything - * in the secrets tdb. */ - if (strcmp(service_principal, salting_principals[i]) != 0) { - kerberos_secrets_store_salting_principal(service_principal, - enctypes[j], - salting_principals[i]); - } - } - - out : - - kerberos_free_data_contents(ctx, &outbuf); - SAFE_FREE(salting_principals[0]); - SAFE_FREE(salting_principals[1]); - SAFE_FREE(salting_principals[2]); - SAFE_FREE(second_principal); -} - -/************************************************************************ - Go through all the possible enctypes for this principal. - ************************************************************************/ - -static void kerberos_derive_salting_principal_direct(krb5_context context, - krb5_ccache ccache, - krb5_enctype *enctypes, - char *service_principal) -{ - int i; - - /* Try for each enctype separately, because the rules are - * different for different enctypes. */ - for (i = 0; enctypes[i] != 0; i++) { - /* Delete secrets entry first. */ - kerberos_secrets_store_salting_principal(service_principal, 0, NULL); -#ifdef ENCTYPE_ARCFOUR_HMAC - if (enctypes[i] == ENCTYPE_ARCFOUR_HMAC) { - /* Of course this'll always work, so just save - * ourselves the effort. */ - continue; - } -#endif - /* Try to figure out what's going on with this - * principal. */ - kerberos_derive_salting_principal_for_enctype(service_principal, - context, - ccache, - enctypes[i], - enctypes); - } -} - -/************************************************************************ - Wrapper function for the above. - ************************************************************************/ - -BOOL kerberos_derive_salting_principal(char *service_principal) -{ - krb5_context context = NULL; - krb5_enctype *enctypes = NULL; - krb5_ccache ccache = NULL; - krb5_error_code ret = 0; - - initialize_krb5_error_table(); - if ((ret = krb5_init_context(&context)) != 0) { - DEBUG(1,("kerberos_derive_cifs_salting_principals: krb5_init_context failed. %s\n", - error_message(ret))); - return False; - } - if ((ret = get_kerberos_allowed_etypes(context, &enctypes)) != 0) { - DEBUG(1,("kerberos_derive_cifs_salting_principals: get_kerberos_allowed_etypes failed. %s\n", - error_message(ret))); - goto out; - } - - if ((ret = krb5_cc_resolve(context, LIBADS_CCACHE_NAME, &ccache)) != 0) { - DEBUG(3, ("get_service_ticket: krb5_cc_resolve for %s failed: %s\n", - LIBADS_CCACHE_NAME, error_message(ret))); - goto out; - } - - kerberos_derive_salting_principal_direct(context, ccache, enctypes, service_principal); - - out: - if (enctypes) { - free_kerberos_etypes(context, enctypes); - } - if (ccache) { - krb5_cc_destroy(context, ccache); - } - if (context) { - krb5_free_context(context); - } - - return ret ? False : True; -} /************************************************************************ - Core function to try and determine what salt is being used for any keytab - keys. - ************************************************************************/ - -BOOL kerberos_derive_cifs_salting_principals(void) -{ - fstring my_fqdn; - char *service = NULL; - krb5_context context = NULL; - krb5_enctype *enctypes = NULL; - krb5_ccache ccache = NULL; - krb5_error_code ret = 0; - BOOL retval = False; - - initialize_krb5_error_table(); - if ((ret = krb5_init_context(&context)) != 0) { - DEBUG(1,("kerberos_derive_cifs_salting_principals: krb5_init_context failed. %s\n", - error_message(ret))); - return False; - } - if ((ret = get_kerberos_allowed_etypes(context, &enctypes)) != 0) { - DEBUG(1,("kerberos_derive_cifs_salting_principals: get_kerberos_allowed_etypes failed. %s\n", - error_message(ret))); - goto out; - } - - if ((ret = krb5_cc_resolve(context, LIBADS_CCACHE_NAME, &ccache)) != 0) { - DEBUG(3, ("get_service_ticket: krb5_cc_resolve for %s failed: %s\n", - LIBADS_CCACHE_NAME, error_message(ret))); - goto out; - } - - if (asprintf(&service, "%s$", global_myname()) != -1) { - strlower_m(service); - kerberos_derive_salting_principal_direct(context, ccache, enctypes, service); - SAFE_FREE(service); - } - if (asprintf(&service, "cifs/%s", global_myname()) != -1) { - strlower_m(service); - kerberos_derive_salting_principal_direct(context, ccache, enctypes, service); - SAFE_FREE(service); - } - if (asprintf(&service, "host/%s", global_myname()) != -1) { - strlower_m(service); - kerberos_derive_salting_principal_direct(context, ccache, enctypes, service); - SAFE_FREE(service); - } - if (asprintf(&service, "cifs/%s.%s", global_myname(), lp_realm()) != -1) { - strlower_m(service); - kerberos_derive_salting_principal_direct(context, ccache, enctypes, service); - SAFE_FREE(service); - } - if (asprintf(&service, "host/%s.%s", global_myname(), lp_realm()) != -1) { - strlower_m(service); - kerberos_derive_salting_principal_direct(context, ccache, enctypes, service); - SAFE_FREE(service); - } - name_to_fqdn(my_fqdn, global_myname()); - if (asprintf(&service, "cifs/%s", my_fqdn) != -1) { - strlower_m(service); - kerberos_derive_salting_principal_direct(context, ccache, enctypes, service); - SAFE_FREE(service); - } - if (asprintf(&service, "host/%s", my_fqdn) != -1) { - strlower_m(service); - kerberos_derive_salting_principal_direct(context, ccache, enctypes, service); - SAFE_FREE(service); - } - - retval = True; - - out: - if (enctypes) { - free_kerberos_etypes(context, enctypes); - } - if (ccache) { - krb5_cc_destroy(context, ccache); - } - if (context) { - krb5_free_context(context); - } - return retval; -} +************************************************************************/ int kerberos_kinit_password(const char *principal, const char *password, diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c index fc87b687d1..80d11d434b 100644 --- a/source3/libads/kerberos_keytab.c +++ b/source3/libads/kerberos_keytab.c @@ -9,6 +9,7 @@ Copyright (C) Rakesh Patel 2004 Copyright (C) Dan Perry 2004 Copyright (C) Jeremy Allison 2004 + Copyright (C) Gerald Carter 2006 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -29,120 +30,35 @@ #ifdef HAVE_KRB5 +/* This MAX_NAME_LEN is a constant defined in krb5.h */ +#ifndef MAX_KEYTAB_NAME_LEN +#define MAX_KEYTAB_NAME_LEN 1100 +#endif + + /********************************************************************** - Adds a single service principal, i.e. 'host' to the system keytab -***********************************************************************/ +**********************************************************************/ -int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc) +static int smb_krb5_kt_add_entry( krb5_context context, krb5_keytab keytab, + krb5_kvno kvno, const char *princ_s, + krb5_enctype *enctypes, krb5_data password ) { krb5_error_code ret = 0; - krb5_context context = NULL; - krb5_keytab keytab = NULL; krb5_kt_cursor cursor; krb5_keytab_entry kt_entry; krb5_principal princ = NULL; - krb5_data password; - krb5_enctype *enctypes = NULL; - krb5_kvno kvno; - - char *principal = NULL; - char *princ_s = NULL; - char *password_s = NULL; -#ifndef MAX_KEYTAB_NAME_LEN -#define MAX_KEYTAB_NAME_LEN 1100 -#endif - char keytab_name[MAX_KEYTAB_NAME_LEN]; /* This MAX_NAME_LEN is a constant defined in krb5.h */ - fstring my_fqdn; int i; char *ktprinc = NULL; ZERO_STRUCT(kt_entry); ZERO_STRUCT(cursor); - - initialize_krb5_error_table(); - ret = krb5_init_context(&context); - if (ret) { - DEBUG(1,("ads_keytab_add_entry: could not krb5_init_context: %s\n",error_message(ret))); - return -1; - } -#ifdef HAVE_WRFILE_KEYTAB /* MIT */ - keytab_name[0] = 'W'; - keytab_name[1] = 'R'; - ret = krb5_kt_default_name(context, (char *) &keytab_name[2], MAX_KEYTAB_NAME_LEN - 4); -#else /* Heimdal */ - ret = krb5_kt_default_name(context, (char *) &keytab_name[0], MAX_KEYTAB_NAME_LEN - 2); -#endif - if (ret) { - DEBUG(1,("ads_keytab_add_entry: krb5_kt_default_name failed (%s)\n", error_message(ret))); - goto out; - } - DEBUG(2,("ads_keytab_add_entry: Using default system keytab: %s\n", (char *) &keytab_name)); - ret = krb5_kt_resolve(context, (char *) &keytab_name, &keytab); - if (ret) { - DEBUG(1,("ads_keytab_add_entry: krb5_kt_resolve failed (%s)\n", error_message(ret))); - goto out; - } - - /* retrieve the password */ - if (!secrets_init()) { - DEBUG(1,("ads_keytab_add_entry: secrets_init failed\n")); - ret = -1; - goto out; - } - password_s = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL); - if (!password_s) { - DEBUG(1,("ads_keytab_add_entry: failed to fetch machine password\n")); - ret = -1; - goto out; - } - password.data = password_s; - password.length = strlen(password_s); - - /* Construct our principal */ - name_to_fqdn(my_fqdn, global_myname()); - strlower_m(my_fqdn); - - if (strchr_m(srvPrinc, '@')) { - /* It's a fully-named principal. */ - asprintf(&princ_s, "%s", srvPrinc); - } else if (srvPrinc[strlen(srvPrinc)-1] == '$') { - /* It's the machine account, as used by smbclient clients. */ - asprintf(&princ_s, "%s@%s", srvPrinc, lp_realm()); - } else { - /* It's a normal service principal. Add the SPN now so that we - * can obtain credentials for it and double-check the salt value - * used to generate the service's keys. */ - asprintf(&princ_s, "%s/%s@%s", srvPrinc, my_fqdn, lp_realm()); - /* Update the directory with the SPN */ - DEBUG(3,("ads_keytab_add_entry: Attempting to add/update '%s'\n", princ_s)); - if (!ADS_ERR_OK(ads_add_service_principal_name(ads, global_myname(), srvPrinc))) { - DEBUG(1,("ads_keytab_add_entry: ads_add_service_principal_name failed.\n")); - goto out; - } - } - - ret = get_kerberos_allowed_etypes(context,&enctypes); - if (ret) { - DEBUG(1,("ads_keytab_add_entry: get_kerberos_allowed_etypes failed (%s)\n",error_message(ret))); - goto out; - } - - /* Guess at how the KDC is salting keys for this principal. */ - kerberos_derive_salting_principal(princ_s); - + ret = smb_krb5_parse_name(context, princ_s, &princ); if (ret) { DEBUG(1,("ads_keytab_add_entry: smb_krb5_parse_name(%s) failed (%s)\n", princ_s, error_message(ret))); goto out; } - kvno = (krb5_kvno) ads_get_kvno(ads, global_myname()); - if (kvno == -1) { /* -1 indicates failure, everything else is OK */ - DEBUG(1,("ads_keytab_add_entry: ads_get_kvno failed to determine the system's kvno.\n")); - ret = -1; - goto out; - } - /* Seek and delete old keytab entries */ ret = krb5_kt_start_seq_get(context, keytab, &cursor); if (ret != KRB5_KT_END && ret != ENOENT ) { @@ -275,15 +191,8 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc) } } - krb5_kt_close(context, keytab); - keytab = NULL; /* Done with keytab now. No double free. */ out: - - SAFE_FREE(principal); - SAFE_FREE(password_s); - SAFE_FREE(princ_s); - { krb5_keytab_entry zero_kt_entry; ZERO_STRUCT(zero_kt_entry); @@ -294,10 +203,7 @@ out: if (princ) { krb5_free_principal(context, princ); } - if (enctypes) { - free_kerberos_etypes(context, enctypes); - } - + { krb5_kt_cursor zero_csr; ZERO_STRUCT(zero_csr); @@ -305,6 +211,157 @@ out: krb5_kt_end_seq_get(context, keytab, &cursor); } } + + return (int)ret; +} + + +/********************************************************************** + Adds a single service principal, i.e. 'host' to the system keytab +***********************************************************************/ + +int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc) +{ + krb5_error_code ret = 0; + krb5_context context = NULL; + krb5_keytab keytab = NULL; + krb5_data password; + krb5_kvno kvno; + krb5_enctype enctypes[4] = { ENCTYPE_DES_CBC_CRC, ENCTYPE_DES_CBC_MD5, 0, 0 }; + char *princ_s = NULL, *short_princ_s = NULL; + char *password_s = NULL; + char *my_fqdn; + char keytab_name[MAX_KEYTAB_NAME_LEN]; + TALLOC_CTX *ctx = NULL; + char *machine_name; + +#if defined(ENCTYPE_ARCFOUR_HMAC) + enctypes[2] = ENCTYPE_ARCFOUR_HMAC; +#endif + + initialize_krb5_error_table(); + ret = krb5_init_context(&context); + if (ret) { + DEBUG(1,("ads_keytab_add_entry: could not krb5_init_context: %s\n",error_message(ret))); + return -1; + } + +#ifdef HAVE_WRFILE_KEYTAB /* MIT */ + keytab_name[0] = 'W'; + keytab_name[1] = 'R'; + ret = krb5_kt_default_name(context, (char *) &keytab_name[2], MAX_KEYTAB_NAME_LEN - 4); +#else /* Heimdal */ + ret = krb5_kt_default_name(context, (char *) &keytab_name[0], MAX_KEYTAB_NAME_LEN - 2); +#endif + if (ret) { + DEBUG(1,("ads_keytab_add_entry: krb5_kt_default_name failed (%s)\n", error_message(ret))); + goto out; + } + DEBUG(2,("ads_keytab_add_entry: Using default system keytab: %s\n", (char *) &keytab_name)); + ret = krb5_kt_resolve(context, (char *) &keytab_name, &keytab); + if (ret) { + DEBUG(1,("ads_keytab_add_entry: krb5_kt_resolve failed (%s)\n", error_message(ret))); + goto out; + } + + /* retrieve the password */ + if (!secrets_init()) { + DEBUG(1,("ads_keytab_add_entry: secrets_init failed\n")); + ret = -1; + goto out; + } + password_s = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL); + if (!password_s) { + DEBUG(1,("ads_keytab_add_entry: failed to fetch machine password\n")); + ret = -1; + goto out; + } + password.data = password_s; + password.length = strlen(password_s); + + /* we need the dNSHostName value here */ + + if ( (ctx = talloc_init("ads_keytab_add_entry")) == NULL ) { + DEBUG(0,("ads_keytab_add_entry: talloc() failed!\n")); + ret = -1; + goto out; + } + + if ( (my_fqdn = ads_get_dnshostname( ads, ctx, global_myname())) == NULL ) { + DEBUG(0,("ads_keytab_add_entry: unable to determine machine account's dns name in AD!\n")); + ret = -1; + goto out; + } + + if ( (machine_name = ads_get_samaccountname( ads, ctx, global_myname())) == NULL ) { + DEBUG(0,("ads_keytab_add_entry: unable to determine machine account's short name in AD!\n")); + ret = -1; + goto out; + } + /*strip the trailing '$' */ + machine_name[strlen(machine_name)-1] = '\0'; + + /* Construct our principal */ + + if (strchr_m(srvPrinc, '@')) { + /* It's a fully-named principal. */ + asprintf(&princ_s, "%s", srvPrinc); + } else if (srvPrinc[strlen(srvPrinc)-1] == '$') { + /* It's the machine account, as used by smbclient clients. */ + asprintf(&princ_s, "%s@%s", srvPrinc, lp_realm()); + } else { + /* It's a normal service principal. Add the SPN now so that we + * can obtain credentials for it and double-check the salt value + * used to generate the service's keys. */ + + asprintf(&princ_s, "%s/%s@%s", srvPrinc, my_fqdn, lp_realm()); + asprintf(&short_princ_s, "%s/%s@%s", srvPrinc, machine_name, lp_realm()); + + /* According to http://support.microsoft.com/kb/326985/en-us, + certain principal names are automatically mapped to the host/... + principal in the AD account. So only create these in the + keytab, not in AD. --jerry */ + + if ( !strequal( srvPrinc, "cifs" ) && !strequal(srvPrinc, "host" ) ) { + DEBUG(3,("ads_keytab_add_entry: Attempting to add/update '%s'\n", princ_s)); + + if (!ADS_ERR_OK(ads_add_service_principal_name(ads, global_myname(), my_fqdn, srvPrinc))) { + DEBUG(1,("ads_keytab_add_entry: ads_add_service_principal_name failed.\n")); + goto out; + } + } + } + + kvno = (krb5_kvno) ads_get_kvno(ads, global_myname()); + if (kvno == -1) { /* -1 indicates failure, everything else is OK */ + DEBUG(1,("ads_keytab_add_entry: ads_get_kvno failed to determine the system's kvno.\n")); + ret = -1; + goto out; + } + + /* add the fqdn principal to the keytab */ + + ret = smb_krb5_kt_add_entry( context, keytab, kvno, princ_s, enctypes, password ); + if ( ret ) { + DEBUG(1,("ads_keytab_add_entry: Failed to add entry to keytab file\n")); + goto out; + } + + /* add the short principal name if we have one */ + + if ( short_princ_s ) { + ret = smb_krb5_kt_add_entry( context, keytab, kvno, short_princ_s, enctypes, password ); + if ( ret ) { + DEBUG(1,("ads_keytab_add_entry: Failed to add short entry to keytab file\n")); + goto out; + } + } + +out: + SAFE_FREE( princ_s ); + SAFE_FREE( short_princ_s ); + TALLOC_FREE( ctx ); + if (keytab) { krb5_kt_close(context, keytab); } @@ -440,94 +497,76 @@ int ads_keytab_create_default(ADS_STRUCT *ads) krb5_kt_cursor cursor; krb5_keytab_entry kt_entry; krb5_kvno kvno; - fstring my_fqdn, my_Fqdn, my_name, my_NAME, my_host_realm; - char *p_fqdn; int i, found = 0; + char *sam_account_name, *upn; char **oldEntries = NULL, *princ_s[26]; + TALLOC_CTX *ctx = NULL; + fstring machine_name; memset(princ_s, '\0', sizeof(princ_s)); - ret = ads_keytab_add_entry(ads, "host"); - if (ret) { + fstrcpy( machine_name, global_myname() ); + + /* these are the main ones we need */ + + if ( (ret = ads_keytab_add_entry(ads, "host") ) != 0 ) { DEBUG(1,("ads_keytab_create_default: ads_keytab_add_entry failed while adding 'host'.\n")); return ret; } - ret = ads_keytab_add_entry(ads, "cifs"); - if (ret) { + + +#if 0 /* don't create the CIFS/... keytab entries since no one except smbd + really needs them and we will fall back to verifying against secrets.tdb */ + + if ( (ret = ads_keytab_add_entry(ads, "cifs")) != 0 ) { DEBUG(1,("ads_keytab_create_default: ads_keytab_add_entry failed while adding 'cifs'.\n")); return ret; } +#endif - fstrcpy(my_name, global_myname()); - strlower_m(my_name); - - fstrcpy(my_NAME, global_myname()); - strupper_m(my_NAME); - - my_fqdn[0] = '\0'; - name_to_fqdn(my_fqdn, global_myname()); - strlower_m(my_fqdn); - - p_fqdn = strchr_m(my_fqdn, '.'); - fstrcpy(my_Fqdn, my_NAME); - if (p_fqdn) { - fstrcat(my_Fqdn, p_fqdn); - } - - fstrcpy(my_host_realm, my_name); - fstrcat(my_host_realm, "."); - fstrcat(my_host_realm, lp_realm()); - strlower_m(my_host_realm); - - asprintf(&princ_s[0], "%s$@%s", my_name, lp_realm()); - asprintf(&princ_s[1], "%s$@%s", my_NAME, lp_realm()); - asprintf(&princ_s[2], "host/%s@%s", my_name, lp_realm()); - asprintf(&princ_s[3], "host/%s@%s", my_NAME, lp_realm()); - asprintf(&princ_s[4], "host/%s@%s", my_fqdn, lp_realm()); - asprintf(&princ_s[5], "host/%s@%s", my_Fqdn, lp_realm()); - asprintf(&princ_s[6], "HOST/%s@%s", my_name, lp_realm()); - asprintf(&princ_s[7], "HOST/%s@%s", my_NAME, lp_realm()); - asprintf(&princ_s[8], "HOST/%s@%s", my_fqdn, lp_realm()); - asprintf(&princ_s[9], "HOST/%s@%s", my_Fqdn, lp_realm()); - asprintf(&princ_s[10], "cifs/%s@%s", my_name, lp_realm()); - asprintf(&princ_s[11], "cifs/%s@%s", my_NAME, lp_realm()); - asprintf(&princ_s[12], "cifs/%s@%s", my_fqdn, lp_realm()); - asprintf(&princ_s[13], "cifs/%s@%s", my_Fqdn, lp_realm()); - asprintf(&princ_s[14], "CIFS/%s@%s", my_name, lp_realm()); - asprintf(&princ_s[15], "CIFS/%s@%s", my_NAME, lp_realm()); - asprintf(&princ_s[16], "CIFS/%s@%s", my_fqdn, lp_realm()); - asprintf(&princ_s[17], "CIFS/%s@%s", my_Fqdn, lp_realm()); - asprintf(&princ_s[18], "cifs/%s.%s@%s", my_name, lp_realm(), lp_realm()); - asprintf(&princ_s[19], "CIFS/%s.%s@%s", my_name, lp_realm(), lp_realm()); - asprintf(&princ_s[20], "host/%s.%s@%s", my_name, lp_realm(), lp_realm()); - asprintf(&princ_s[21], "HOST/%s.%s@%s", my_name, lp_realm(), lp_realm()); - - /* when dnsdomain == realm, don't add duplicate principal */ - if (!strequal(my_host_realm, my_fqdn)) { - asprintf(&princ_s[22], "cifs/%s@%s", my_host_realm, lp_realm()); - asprintf(&princ_s[23], "CIFS/%s@%s", my_host_realm, lp_realm()); - asprintf(&princ_s[24], "host/%s@%s", my_host_realm, lp_realm()); - asprintf(&princ_s[25], "HOST/%s@%s", my_host_realm, lp_realm()); - } - - for (i = 0; i < sizeof(princ_s) / sizeof(princ_s[0]); i++) { - if (princ_s[i] != NULL) { - ret = ads_keytab_add_entry(ads, princ_s[i]); - if (ret != 0) { - DEBUG(1,("ads_keytab_create_default: ads_keytab_add_entry failed while adding '%s'.\n", princ_s[i])); - } - SAFE_FREE(princ_s[i]); + if ( (ctx = talloc_init("ads_keytab_create_default")) == NULL ) { + DEBUG(0,("ads_keytab_create_default: talloc() failed!\n")); + return -1; + } + + /* now add the userPrincipalName and sAMAccountName entries */ + + if ( (sam_account_name = ads_get_samaccountname( ads, ctx, machine_name)) == NULL ) { + DEBUG(0,("ads_keytab_add_entry: unable to determine machine account's name in AD!\n")); + TALLOC_FREE( ctx ); + return -1; + } + + if ( (ret = ads_keytab_add_entry(ads, sam_account_name )) != 0 ) { + DEBUG(1,("ads_keytab_create_default: ads_keytab_add_entry failed while adding sAMAccountName (%s)\n", + sam_account_name)); + return ret; + } + + /* remember that not every machine account will have a upn */ + + upn = ads_get_upn( ads, ctx, machine_name); + if ( upn ) { + if ( (ret = ads_keytab_add_entry(ads, upn)) != 0 ) { + DEBUG(1,("ads_keytab_create_default: ads_keytab_add_entry failed while adding UPN (%s)\n", + upn)); + TALLOC_FREE( ctx ); + return ret; } } - kvno = (krb5_kvno) ads_get_kvno(ads, global_myname()); + TALLOC_FREE( ctx ); + + /* Now loop through the keytab and update any other existing entries... */ + + kvno = (krb5_kvno) ads_get_kvno(ads, machine_name); if (kvno == -1) { DEBUG(1,("ads_keytab_create_default: ads_get_kvno failed to determine the system's kvno.\n")); return -1; } - - DEBUG(3,("ads_keytab_create_default: Searching for keytab entries to preserve and update.\n")); - /* Now loop through the keytab and update any other existing entries... */ + + DEBUG(3,("ads_keytab_create_default: Searching for keytab entries to " + "preserve and update.\n")); ZERO_STRUCT(kt_entry); ZERO_STRUCT(cursor); diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 525a9cfa27..3aa0860809 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -202,9 +202,13 @@ static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context au BOOL auth_ok = False; char *password_s = NULL; krb5_data password; - krb5_enctype *enctypes = NULL; + krb5_enctype enctypes[4] = { ENCTYPE_DES_CBC_CRC, ENCTYPE_DES_CBC_MD5, 0, 0 }; int i; +#if defined(ENCTYPE_ARCFOUR_HMAC) + enctypes[2] = ENCTYPE_ARCFOUR_HMAC; +#endif + ZERO_STRUCTP(keyblock); if (!secrets_init()) { @@ -223,12 +227,6 @@ static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context au /* CIFS doesn't use addresses in tickets. This would break NAT. JRA */ - if ((ret = get_kerberos_allowed_etypes(context, &enctypes))) { - DEBUG(1,("ads_secrets_verify_ticket: krb5_get_permitted_enctypes failed (%s)\n", - error_message(ret))); - goto out; - } - p_packet->length = ticket->length; p_packet->data = (krb5_pointer)ticket->data; @@ -273,8 +271,6 @@ static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context au } out: - - free_kerberos_etypes(context, enctypes); SAFE_FREE(password_s); return auth_ok; diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 58eca99f9e..a8ee770582 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -5,6 +5,7 @@ Copyright (C) Remus Koos 2001 Copyright (C) Jim McDonough 2002 Copyright (C) Guenther Deschner 2005 + Copyright (C) Gerald Carter 2006 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -286,15 +287,8 @@ got_connection: DEBUG(3,("Connected to LDAP server %s\n", inet_ntoa(ads->ldap_ip))); if (!ads->auth.user_name) { - /* have to use the userPrincipalName value here and - not servicePrincipalName; found by Guenther Deschner @ Sernet. - - Is this still correct? The comment does not match - the code. --jerry - - Yes it is :) - - Guenther - */ + /* Must use the userPrincipalName value here or sAMAccountName + and not servicePrincipalName; found by Guenther Deschner */ asprintf(&ads->auth.user_name, "%s$", global_myname() ); } @@ -1403,20 +1397,21 @@ ADS_STATUS ads_clear_service_principal_names(ADS_STRUCT *ads, const char *machin * (found by hostname) in AD. * @param ads An initialized ADS_STRUCT * @param machine_name the NetBIOS name of the computer, which is used to identify the computer account. + * @param my_fqdn The fully qualified DNS name of the machine * @param spn A string of the service principal to add, i.e. 'host' * @return 0 upon sucess, or non-zero if a failure occurs **/ -ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_name, const char *spn) +ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_name, + const char *my_fqdn, const char *spn) { ADS_STATUS ret; TALLOC_CTX *ctx; LDAPMessage *res = NULL; - char *psp1, *psp2, *psp3; + char *psp1, *psp2; ADS_MODLIST mods; - fstring my_fqdn; char *dn_string = NULL; - const char *servicePrincipalName[4] = {NULL, NULL, NULL, NULL}; + const char *servicePrincipalName[3] = {NULL, NULL, NULL}; ret = ads_find_machine_acct(ads, (void **)(void *)&res, machine_name); if (!ADS_ERR_OK(ret) || ads_count_replies(ads, res) != 1) { @@ -1434,78 +1429,59 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n return ADS_ERROR(LDAP_NO_MEMORY); } - name_to_fqdn(my_fqdn, machine_name); - strlower_m(my_fqdn); - - /* Add the extra principal */ - psp1 = talloc_asprintf(ctx, "%s/%s", spn, machine_name); - if (!psp1) { + /* add short name spn */ + + if ( (psp1 = talloc_asprintf(ctx, "%s/%s", spn, machine_name)) == NULL ) { talloc_destroy(ctx); ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_MEMORY); } - strupper_m(psp1); strlower_m(&psp1[strlen(spn)]); - DEBUG(5,("ads_add_service_principal_name: INFO: Adding %s to host %s\n", psp1, machine_name)); servicePrincipalName[0] = psp1; - psp2 = talloc_asprintf(ctx, "%s/%s.%s", spn, machine_name, ads->config.realm); - if (!psp2) { - talloc_destroy(ctx); - ads_msgfree(ads, res); - return ADS_ERROR(LDAP_NO_MEMORY); - } + + DEBUG(5,("ads_add_service_principal_name: INFO: Adding %s to host %s\n", + psp1, machine_name)); + + /* add fully qualified spn */ + + if ( (psp2 = talloc_asprintf(ctx, "%s/%s", spn, my_fqdn)) == NULL ) { + ret = ADS_ERROR(LDAP_NO_MEMORY); + goto out; + } strupper_m(psp2); strlower_m(&psp2[strlen(spn)]); - DEBUG(5,("ads_add_service_principal_name: INFO: Adding %s to host %s\n", psp2, machine_name)); servicePrincipalName[1] = psp2; - /* Add another principal in case the realm != the DNS domain, so that - * the KDC doesn't send "server principal unknown" errors to clients - * which use the DNS name in determining service principal names. */ - psp3 = talloc_asprintf(ctx, "%s/%s", spn, my_fqdn); - if (!psp3) { - talloc_destroy(ctx); - ads_msgfree(ads, res); - return ADS_ERROR(LDAP_NO_MEMORY); - } + DEBUG(5,("ads_add_service_principal_name: INFO: Adding %s to host %s\n", + psp2, machine_name)); - strupper_m(psp3); - strlower_m(&psp3[strlen(spn)]); - if (strcmp(psp2, psp3) != 0) { - DEBUG(5,("ads_add_service_principal_name: INFO: Adding %s to host %s\n", psp3, machine_name)); - servicePrincipalName[2] = psp3; - } - - if (!(mods = ads_init_mods(ctx))) { - talloc_destroy(ctx); - ads_msgfree(ads, res); - return ADS_ERROR(LDAP_NO_MEMORY); + if ( (mods = ads_init_mods(ctx)) == NULL ) { + ret = ADS_ERROR(LDAP_NO_MEMORY); + goto out; } + ret = ads_add_strlist(ctx, &mods, "servicePrincipalName", servicePrincipalName); if (!ADS_ERR_OK(ret)) { DEBUG(1,("ads_add_service_principal_name: Error: Updating Service Principals in LDAP\n")); - talloc_destroy(ctx); - ads_msgfree(ads, res); - return ret; + goto out; } - dn_string = ads_get_dn(ads, res); - if (!dn_string) { - talloc_destroy(ctx); - ads_msgfree(ads, res); - return ADS_ERROR(LDAP_NO_MEMORY); + + if ( (dn_string = ads_get_dn(ads, res)) == NULL ) { + ret = ADS_ERROR(LDAP_NO_MEMORY); + goto out; } + ret = ads_gen_mod(ads, dn_string, mods); ads_memfree(ads,dn_string); if (!ADS_ERR_OK(ret)) { DEBUG(1,("ads_add_service_principal_name: Error: Updating Service Principals in LDAP\n")); - talloc_destroy(ctx); - ads_msgfree(ads, res); - return ret; + goto out; } - talloc_destroy(ctx); + out: + TALLOC_FREE( ctx ); ads_msgfree(ads, res); return ret; } @@ -2236,13 +2212,9 @@ static time_t ads_parse_time(const char *str) return timegm(&tm); } -/** - * Find the servers name and realm - this can be done before authentication - * The ldapServiceName field on w2k looks like this: - * vnet3.home.samba.org:win2000-vnet3$@VNET3.HOME.SAMBA.ORG - * @param ads connection to ads server - * @return status of search - **/ +/******************************************************************** +********************************************************************/ + ADS_STATUS ads_current_time(ADS_STRUCT *ads) { const char *attrs[] = {"currentTime", NULL}; @@ -2252,7 +2224,7 @@ ADS_STATUS ads_current_time(ADS_STRUCT *ads) TALLOC_CTX *ctx; ADS_STRUCT *ads_s = ads; - if (!(ctx = talloc_init("ads_server_info"))) { + if (!(ctx = talloc_init("ads_current_time"))) { return ADS_ERROR(LDAP_NO_MEMORY); } @@ -2272,14 +2244,12 @@ ADS_STATUS ads_current_time(ADS_STRUCT *ads) status = ads_do_search(ads_s, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); if (!ADS_ERR_OK(status)) { - talloc_destroy(ctx); goto done; } timestr = ads_pull_string(ads_s, ctx, res, "currentTime"); if (!timestr) { ads_msgfree(ads, res); - talloc_destroy(ctx); status = ADS_ERROR(LDAP_NO_RESULTS_RETURNED); goto done; } @@ -2307,6 +2277,60 @@ done: return status; } +/******************************************************************** +********************************************************************/ + +ADS_STATUS ads_domain_func_level(ADS_STRUCT *ads, uint32 *val) +{ + const char *attrs[] = {"domainFunctionality", NULL}; + ADS_STATUS status; + void *res; + ADS_STRUCT *ads_s = ads; + + *val = DS_DOMAIN_FUNCTION_2000; + + /* establish a new ldap tcp session if necessary */ + + if ( !ads->ld ) { + if ( (ads_s = ads_init( ads->server.realm, ads->server.workgroup, + ads->server.ldap_server )) == NULL ) + { + goto done; + } + ads_s->auth.flags = ADS_AUTH_ANON_BIND; + status = ads_connect( ads_s ); + if ( !ADS_ERR_OK(status)) + goto done; + } + + /* If the attribute does not exist assume it is a Windows 2000 + functional domain */ + + status = ads_do_search(ads_s, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); + if (!ADS_ERR_OK(status)) { + if ( status.err.rc == LDAP_NO_SUCH_ATTRIBUTE ) { + status = ADS_SUCCESS; + } + goto done; + } + + if ( !ads_pull_uint32(ads_s, res, "domainFunctionality", val) ) { + DEBUG(5,("ads_domain_func_level: Failed to pull the domainFunctionality attribute.\n")); + } + DEBUG(3,("ads_domain_func_level: %d\n", *val)); + + + ads_msgfree(ads, res); + +done: + /* free any temporary ads connections */ + if ( ads_s != ads ) { + ads_destroy( &ads_s ); + } + + return status; +} + /** * find the domain sid for our domain * @param ads connection to ads server @@ -2617,4 +2641,100 @@ int ads_pull_sids_from_extendeddn(ADS_STRUCT *ads, return dn_count; } +/******************************************************************** +********************************************************************/ + +char* ads_get_dnshostname( ADS_STRUCT *ads, TALLOC_CTX *ctx, const char *machine_name ) +{ + LDAPMessage *res = NULL; + ADS_STATUS status; + int count = 0; + char *name = NULL; + + status = ads_find_machine_acct(ads, (void **)(void *)&res, global_myname()); + if (!ADS_ERR_OK(status)) { + DEBUG(0,("ads_get_dnshostname: Failed to find account for %s\n", + global_myname())); + goto out; + } + + if ( (count = ads_count_replies(ads, res)) != 1 ) { + DEBUG(1,("ads_get_dnshostname: %d entries returned!\n", count)); + goto out; + } + + if ( (name = ads_pull_string(ads, ctx, res, "dNSHostName")) == NULL ) { + DEBUG(0,("ads_get_dnshostname: No dNSHostName attribute!\n")); + } + +out: + ads_msgfree(ads, res); + + return name; +} + +/******************************************************************** +********************************************************************/ + +char* ads_get_upn( ADS_STRUCT *ads, TALLOC_CTX *ctx, const char *machine_name ) +{ + LDAPMessage *res = NULL; + ADS_STATUS status; + int count = 0; + char *name = NULL; + + status = ads_find_machine_acct(ads, (void **)(void *)&res, global_myname()); + if (!ADS_ERR_OK(status)) { + DEBUG(0,("ads_get_dnshostname: Failed to find account for %s\n", + global_myname())); + goto out; + } + + if ( (count = ads_count_replies(ads, res)) != 1 ) { + DEBUG(1,("ads_get_dnshostname: %d entries returned!\n", count)); + goto out; + } + + if ( (name = ads_pull_string(ads, ctx, res, "userPrincipalName")) == NULL ) { + DEBUG(0,("ads_get_dnshostname: No userPrincipalName attribute!\n")); + } + +out: + ads_msgfree(ads, res); + + return name; +} + +/******************************************************************** +********************************************************************/ + +char* ads_get_samaccountname( ADS_STRUCT *ads, TALLOC_CTX *ctx, const char *machine_name ) +{ + LDAPMessage *res = NULL; + ADS_STATUS status; + int count = 0; + char *name = NULL; + + status = ads_find_machine_acct(ads, (void **)(void *)&res, global_myname()); + if (!ADS_ERR_OK(status)) { + DEBUG(0,("ads_get_dnshostname: Failed to find account for %s\n", + global_myname())); + goto out; + } + + if ( (count = ads_count_replies(ads, res)) != 1 ) { + DEBUG(1,("ads_get_dnshostname: %d entries returned!\n", count)); + goto out; + } + + if ( (name = ads_pull_string(ads, ctx, res, "sAMAccountName")) == NULL ) { + DEBUG(0,("ads_get_dnshostname: No sAMAccountName attribute!\n")); + } + +out: + ads_msgfree(ads, res); + + return name; +} + #endif diff --git a/source3/libads/util.c b/source3/libads/util.c index 8e3001ccb0..eb6dccb3af 100644 --- a/source3/libads/util.c +++ b/source3/libads/util.c @@ -48,14 +48,6 @@ ADS_STATUS ads_change_trust_account_password(ADS_STRUCT *ads, char *host_princip goto failed; } - /* Determine if the KDC is salting keys for this principal in a - * non-obvious way. */ - if (!kerberos_derive_salting_principal(host_principal)) { - DEBUG(1,("Failed to determine correct salting principal for %s\n", host_principal)); - ret = ADS_ERROR_SYSTEM(EACCES); - goto failed; - } - failed: SAFE_FREE(password); return ret; -- cgit From 361fef49c50263313d61cdaad5a4fbe2c5ddb78d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 11 Jul 2006 20:50:50 +0000 Subject: r16955: Fix an uninitialized var -- Jerry, please check. (This used to be commit bf701f51294dacd0d4077b5304772c40119460eb) --- source3/libads/kerberos.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index a25daf5399..d1b1f7240c 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -334,13 +334,13 @@ char* kerberos_secrets_fetch_des_salt( void ) return False; } + salt = (char*)secrets_fetch( key, NULL ); + if ( !salt ) { DEBUG(8,("kerberos_secrets_fetch_des_salt: NULL salt!\n")); secrets_delete( key ); } - salt = (char*)secrets_fetch( key, NULL ); - SAFE_FREE( key ); return salt; -- cgit From 69f0c8aef13af60c3d49e3e0e1b2bc8f1e6bb36f Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 11 Jul 2006 21:09:13 +0000 Subject: r16957: fix cut-n-paste error. The check for 'if (\!salt)' make no sense when fetching the DES salting principal (This used to be commit baf554c7934cbd591635196453c19d402358e073) --- source3/libads/kerberos.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index d1b1f7240c..9f197fb50c 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -336,11 +336,6 @@ char* kerberos_secrets_fetch_des_salt( void ) salt = (char*)secrets_fetch( key, NULL ); - if ( !salt ) { - DEBUG(8,("kerberos_secrets_fetch_des_salt: NULL salt!\n")); - secrets_delete( key ); - } - SAFE_FREE( key ); return salt; -- cgit From de5d9675052e311290211ce3656bb050497ae8cf Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 13 Jul 2006 00:11:34 +0000 Subject: r17003: Fix coverity #303 - possible null deref. Jerry please check this is your new code. Jeremy. (This used to be commit 144067783d1c56b574911532f074bdaa7cea9c6e) --- source3/libads/kerberos.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 9f197fb50c..af4ba86831 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -311,6 +311,7 @@ BOOL kerberos_secrets_store_des_salt( const char* salt ) if ( !salt ) { DEBUG(8,("kerberos_secrets_store_des_salt: deleting salt\n")); secrets_delete( key ); + return True; } DEBUG(3,("kerberos_secrets_store_des_salt: Storing salt \"%s\"\n", salt)); -- cgit From 846e939260c30d902952d95413d9cc3d06a82173 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 17 Jul 2006 15:00:49 +0000 Subject: r17089: Fix a possible null dereference and some memleaks. Jerry, please check. Thanks, Volker (This used to be commit b87c4952216b6302b0e1f22689b5a36b6aa65349) --- source3/libads/cldap.c | 7 +++++++ source3/libads/ldap.c | 1 + 2 files changed, 8 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/cldap.c b/source3/libads/cldap.c index f67372805f..2e96270e90 100644 --- a/source3/libads/cldap.c +++ b/source3/libads/cldap.c @@ -191,6 +191,11 @@ static int recv_cldap_netlogon(int sock, struct cldap_netlogon_reply *reply) char *p; blob = data_blob(NULL, 8192); + if (blob.data == NULL) { + DEBUG(1, ("data_blob failed\n")); + errno = ENOMEM; + return -1; + } /* Setup timeout */ gotalarm = 0; @@ -206,6 +211,7 @@ static int recv_cldap_netlogon(int sock, struct cldap_netlogon_reply *reply) if (ret <= 0) { DEBUG(1,("no reply received to cldap netlogon\n")); + data_blob_free(&blob); return -1; } blob.length = ret; @@ -227,6 +233,7 @@ static int recv_cldap_netlogon(int sock, struct cldap_netlogon_reply *reply) asn1_end_tag(&data); if (data.has_error) { + data_blob_free(&blob); asn1_free(&data); DEBUG(1,("Failed to parse cldap reply\n")); return -1; diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index a8ee770582..5d972b35fc 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -134,6 +134,7 @@ BOOL ads_try_connect(ADS_STRUCT *ads, const char *server ) if ( !ads_cldap_netlogon( srv, ads->server.realm, &cldap_reply ) ) { DEBUG(3,("ads_try_connect: CLDAP request %s failed.\n", srv)); + SAFE_FREE( srv ); return False; } -- cgit From f3550d82a76840d23be9fe2fa6739a81d426bf5f Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 19 Jul 2006 20:53:10 +0000 Subject: r17146: Starting to cleanout my local tree some * add code to lookup NS records (in prep for later coe that does DNS updates as part of the net ads join) (This used to be commit 36d4970646638a2719ebb05a091c951183535987) --- source3/libads/dns.c | 215 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 199 insertions(+), 16 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/dns.c b/source3/libads/dns.c index 321b435527..570f9583f0 100644 --- a/source3/libads/dns.c +++ b/source3/libads/dns.c @@ -46,6 +46,7 @@ # define T_A ns_t_a #endif # define T_SRV ns_t_srv +# define T_NS ns_t_ns #else # ifdef HFIXEDSZ # define NS_HFIXEDSZ HFIXEDSZ @@ -197,6 +198,46 @@ static BOOL ads_dns_parse_rr_srv( TALLOC_CTX *ctx, uint8 *start, uint8 *end, return True; } +/********************************************************************* +*********************************************************************/ + +static BOOL ads_dns_parse_rr_ns( TALLOC_CTX *ctx, uint8 *start, uint8 *end, + uint8 **ptr, struct dns_rr_ns *nsrec ) +{ + struct dns_rr rr; + uint8 *p; + pstring nsname; + int namelen; + + if ( !start || !end || !nsrec || !*ptr) + return -1; + + /* Parse the RR entry. Coming out of the this, ptr is at the beginning + of the next record */ + + if ( !ads_dns_parse_rr( ctx, start, end, ptr, &rr ) ) { + DEBUG(1,("ads_dns_parse_rr_ns: Failed to parse RR record\n")); + return False; + } + + if ( rr.type != T_NS ) { + DEBUG(1,("ads_dns_parse_rr_ns: Bad answer type (%d)\n", rr.type)); + return False; + } + + p = rr.rdata; + + /* ame server hostname */ + + namelen = dn_expand( start, end, p, nsname, sizeof(nsname) ); + if ( namelen < 0 ) { + DEBUG(1,("ads_dns_parse_rr_ns: Failed to uncompress name!\n")); + return False; + } + nsrec->hostname = talloc_strdup( ctx, nsname ); + + return True; +} /********************************************************************* Sort SRV record list based on weight and priority. See RFC 2782. @@ -230,27 +271,16 @@ static int dnssrvcmp( struct dns_rr_srv *a, struct dns_rr_srv *b ) } /********************************************************************* - Simple wrapper for a DNS SRV query + Simple wrapper for a DNS query *********************************************************************/ -NTSTATUS ads_dns_lookup_srv( TALLOC_CTX *ctx, const char *name, struct dns_rr_srv **dclist, int *numdcs ) +static NTSTATUS dns_send_req( TALLOC_CTX *ctx, const char *name, int q_type, + uint8 **buf, int *resp_length ) { uint8 *buffer = NULL; size_t buf_len; - int resp_len = NS_PACKETSZ; - struct dns_rr_srv *dcs = NULL; - int query_count, answer_count, auth_count, additional_count; - uint8 *p = buffer; - int rrnum; - int idx = 0; - - if ( !ctx || !name || !dclist ) { - return NT_STATUS_INVALID_PARAMETER; - } + int resp_len = NS_PACKETSZ; - /* Send the request. May have to loop several times in case - of large replies */ - do { if ( buffer ) TALLOC_FREE( buffer ); @@ -262,13 +292,47 @@ NTSTATUS ads_dns_lookup_srv( TALLOC_CTX *ctx, const char *name, struct dns_rr_sr return NT_STATUS_NO_MEMORY; } - if ( (resp_len = res_query(name, C_IN, T_SRV, buffer, buf_len)) < 0 ) { + if ( (resp_len = res_query(name, C_IN, q_type, buffer, buf_len)) < 0 ) { DEBUG(1,("ads_dns_lookup_srv: Failed to resolve %s (%s)\n", name, strerror(errno))); TALLOC_FREE( buffer ); return NT_STATUS_UNSUCCESSFUL; } } while ( buf_len < resp_len && resp_len < MAX_DNS_PACKET_SIZE ); + + *buf = buffer; + *resp_length = resp_len; + + return NT_STATUS_OK; +} + +/********************************************************************* + Simple wrapper for a DNS SRV query +*********************************************************************/ + +static NTSTATUS ads_dns_lookup_srv( TALLOC_CTX *ctx, const char *name, struct dns_rr_srv **dclist, int *numdcs ) +{ + uint8 *buffer = NULL; + int resp_len = 0; + struct dns_rr_srv *dcs = NULL; + int query_count, answer_count, auth_count, additional_count; + uint8 *p = buffer; + int rrnum; + int idx = 0; + NTSTATUS status; + + if ( !ctx || !name || !dclist ) { + return NT_STATUS_INVALID_PARAMETER; + } + + /* Send the request. May have to loop several times in case + of large replies */ + status = dns_send_req( ctx, name, T_SRV, &buffer, &resp_len ); + if ( !NT_STATUS_IS_OK(status) ) { + DEBUG(0,("ads_dns_lookup_srv: Failed to send DNS query (%s)\n", + nt_errstr(status))); + return status; + } p = buffer; /* For some insane reason, the ns_initparse() et. al. routines are only @@ -361,6 +425,125 @@ NTSTATUS ads_dns_lookup_srv( TALLOC_CTX *ctx, const char *name, struct dns_rr_sr return NT_STATUS_OK; } +/********************************************************************* + Simple wrapper for a DNS NS query +*********************************************************************/ + +NTSTATUS ads_dns_lookup_ns( TALLOC_CTX *ctx, const char *dnsdomain, struct dns_rr_ns **nslist, int *numns ) +{ + uint8 *buffer = NULL; + int resp_len = 0; + struct dns_rr_ns *nsarray = NULL; + int query_count, answer_count, auth_count, additional_count; + uint8 *p; + int rrnum; + int idx = 0; + NTSTATUS status; + + if ( !ctx || !dnsdomain || !nslist ) { + return NT_STATUS_INVALID_PARAMETER; + } + + /* Send the request. May have to loop several times in case + of large replies */ + + status = dns_send_req( ctx, dnsdomain, T_NS, &buffer, &resp_len ); + if ( !NT_STATUS_IS_OK(status) ) { + DEBUG(0,("ads_dns_lookup_ns: Failed to send DNS query (%s)\n", + nt_errstr(status))); + return status; + } + p = buffer; + + /* For some insane reason, the ns_initparse() et. al. routines are only + available in libresolv.a, and not the shared lib. Who knows why.... + So we have to parse the DNS reply ourselves */ + + /* Pull the answer RR's count from the header. Use the NMB ordering macros */ + + query_count = RSVAL( p, 4 ); + answer_count = RSVAL( p, 6 ); + auth_count = RSVAL( p, 8 ); + additional_count = RSVAL( p, 10 ); + + DEBUG(4,("ads_dns_lookup_ns: %d records returned in the answer section.\n", + answer_count)); + + if ( (nsarray = TALLOC_ARRAY(ctx, struct dns_rr_ns, answer_count)) == NULL ) { + DEBUG(0,("ads_dns_lookup_ns: talloc() failure for %d char*'s\n", + answer_count)); + return NT_STATUS_NO_MEMORY; + } + + /* now skip the header */ + + p += NS_HFIXEDSZ; + + /* parse the query section */ + + for ( rrnum=0; rrnum Date: Tue, 25 Jul 2006 19:59:35 +0000 Subject: r17239: BUG 3959: patch from William Charles to fix a segv in the DNS SRV lookups dur to calling rand() (This used to be commit be12519fd8a7ccd8400fd298e05921eda56b4e16) --- source3/libads/dns.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/dns.c b/source3/libads/dns.c index 570f9583f0..558c7f75ba 100644 --- a/source3/libads/dns.c +++ b/source3/libads/dns.c @@ -245,17 +245,11 @@ static BOOL ads_dns_parse_rr_ns( TALLOC_CTX *ctx, uint8 *start, uint8 *end, static int dnssrvcmp( struct dns_rr_srv *a, struct dns_rr_srv *b ) { - BOOL init = False; - - if ( !init ) { - srand( (uint32)time(NULL) ); - } - if ( a->priority == b->priority ) { /* randomize entries with an equal weight and priority */ if ( a->weight == b->weight ) - return rand() % 2 ? -1 : 1; + return 0; /* higher weights should be sorted lower */ if ( a->weight > b->weight ) -- cgit From 1a0b57b5f523bdf787a8024303b661ea9004215f Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 25 Jul 2006 20:11:03 +0000 Subject: r17242: BUG 3957: make sure to zero memory in the SRV hostlist in case there is not an A record for each SRV name (This used to be commit 42608b8bb974e1bd88cf2105bf1774622c045458) --- source3/libads/dns.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/dns.c b/source3/libads/dns.c index 558c7f75ba..903d19b753 100644 --- a/source3/libads/dns.c +++ b/source3/libads/dns.c @@ -343,7 +343,7 @@ static NTSTATUS ads_dns_lookup_srv( TALLOC_CTX *ctx, const char *name, struct dn DEBUG(4,("ads_dns_lookup_srv: %d records returned in the answer section.\n", answer_count)); - if ( (dcs = TALLOC_ARRAY(ctx, struct dns_rr_srv, answer_count)) == NULL ) { + if ( (dcs = TALLOC_ZERO_ARRAY(ctx, struct dns_rr_srv, answer_count)) == NULL ) { DEBUG(0,("ads_dns_lookup_srv: talloc() failure for %d char*'s\n", answer_count)); return NT_STATUS_NO_MEMORY; -- cgit From fd8bae8b1660acefd327121ef3d8a356cb0c09fa Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 31 Jul 2006 20:51:55 +0000 Subject: r17345: Some C++ warnings (This used to be commit 21c8fa2fc8bfd35d203b089ff61efc7c292b4dc0) --- source3/libads/kerberos.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index af4ba86831..910207968c 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -45,7 +45,8 @@ kerb_prompter(krb5_context ctx, void *data, memset(prompts[0].reply->data, '\0', prompts[0].reply->length); if (prompts[0].reply->length > 0) { if (data) { - strncpy(prompts[0].reply->data, data, prompts[0].reply->length-1); + strncpy(prompts[0].reply->data, (const char *)data, + prompts[0].reply->length-1); prompts[0].reply->length = strlen(prompts[0].reply->data); } else { prompts[0].reply->length = 0; -- cgit From 7c94b93af60d12bf8ffcd8d543e727878b82ddbf Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 14 Aug 2006 12:42:46 +0000 Subject: r17535: Reformatting, this had many tabs instead of ^$ (This used to be commit 0f483cf66c203d8590998b83cbeeb236ba06ab63) --- source3/libads/ldap.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 5d972b35fc..5ff1ce435d 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -47,28 +47,28 @@ static SIG_ATOMIC_T gotalarm; /*************************************************************** Signal function to tell us we timed out. ****************************************************************/ - + static void gotalarm_sig(void) { gotalarm = 1; } - + LDAP *ldap_open_with_timeout(const char *server, int port, unsigned int to) { LDAP *ldp = NULL; - + /* Setup timeout */ gotalarm = 0; CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig); alarm(to); /* End setup timeout. */ - + ldp = ldap_open(server, port); - + /* Teardown timeout. */ CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN); alarm(0); - + return ldp; } -- cgit From b757699e8b14fb0d5780e2513ffe64c087f5871d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 14 Aug 2006 12:54:37 +0000 Subject: r17536: Add a debug message citing the reason why an LDAP connection failed, inspired by Christian M Ambach . Volker (This used to be commit cf7c83d462dc766fa6f48728d0a4e8d534cc2bd4) --- source3/libads/ldap.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 5ff1ce435d..2ceafedd30 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -65,6 +65,11 @@ static void gotalarm_sig(void) ldp = ldap_open(server, port); + if (ldp == NULL) { + DEBUG(2,("Could not open LDAP connection to %s:%d: %s\n", + server, port, strerror(errno))); + } + /* Teardown timeout. */ CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN); alarm(0); -- cgit From c804dd01171903440cd2c90153d62ab549d6b800 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 15 Aug 2006 09:53:16 +0000 Subject: r17551: Move some DEBUG to d_printf in interactive functions and return NO_LOGON_SERVERS if no domain controller was found. Thanks to Michael Adam . Volker (This used to be commit d44599de3a61707a32851f37ddfb2425949622f8) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 2ceafedd30..52426c31ae 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -287,7 +287,7 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) goto got_connection; } - return ADS_ERROR_SYSTEM(errno?errno:ENOENT); + return ADS_ERROR_NT(NT_STATUS_NO_LOGON_SERVERS); got_connection: DEBUG(3,("Connected to LDAP server %s\n", inet_ntoa(ads->ldap_ip))); -- cgit From ac2fa9f41445d81bb45e385520d0fbba608956b4 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 17 Aug 2006 13:46:02 +0000 Subject: r17589: Check in the really uncontroversial patch from Michael (This used to be commit de76217cfb9d20431189e838999a634e4de067a9) --- source3/libads/ads_status.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ads_status.c b/source3/libads/ads_status.c index 536ef766e3..5a4165c2f9 100644 --- a/source3/libads/ads_status.c +++ b/source3/libads/ads_status.c @@ -72,6 +72,9 @@ NTSTATUS ads_ntstatus(ADS_STATUS status) if (status.error_type == ENUM_ADS_ERROR_NT){ return status.err.nt_status; } + if (status.error_type == ENUM_ADS_ERROR_SYSTEM) { + return map_nt_error_from_unix(status.err.rc); + } #ifdef HAVE_LDAP if ((status.error_type == ENUM_ADS_ERROR_LDAP) && (status.err.rc == LDAP_NO_MEMORY)) { @@ -84,6 +87,8 @@ NTSTATUS ads_ntstatus(ADS_STATUS status) return NT_STATUS_LOGON_FAILURE; } else if (status.err.rc == KRB5_KDC_UNREACH) { return NT_STATUS_NO_LOGON_SERVERS; + } else if (status.err.rc == KRB5KRB_AP_ERR_SKEW) { + return NT_STATUS_TIME_DIFFERENCE_AT_DC; } } #endif -- cgit From 41a4496b20e510dc47fe2b816196cef6fe937cea Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 18 Aug 2006 15:10:46 +0000 Subject: r17606: Introduce krb5_to_ntstatus. Thanks to Michael Adam Volker (This used to be commit 6e641c90b8f52a822a83701cdf305c60416d7f0c) --- source3/libads/ads_status.c | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_status.c b/source3/libads/ads_status.c index 5a4165c2f9..00427936ad 100644 --- a/source3/libads/ads_status.c +++ b/source3/libads/ads_status.c @@ -69,30 +69,29 @@ ADS_STATUS ads_build_nt_error(enum ads_error_type etype, */ NTSTATUS ads_ntstatus(ADS_STATUS status) { - if (status.error_type == ENUM_ADS_ERROR_NT){ + switch (status.error_type) { + case ENUM_ADS_ERROR_NT: return status.err.nt_status; - } - if (status.error_type == ENUM_ADS_ERROR_SYSTEM) { + case ENUM_ADS_ERROR_SYSTEM: return map_nt_error_from_unix(status.err.rc); - } #ifdef HAVE_LDAP - if ((status.error_type == ENUM_ADS_ERROR_LDAP) - && (status.err.rc == LDAP_NO_MEMORY)) { - return NT_STATUS_NO_MEMORY; - } + case ENUM_ADS_ERROR_LDAP: + if (status.err.rc == LDAP_NO_MEMORY) { + return NT_STATUS_NO_MEMORY; + } + break; #endif #ifdef HAVE_KRB5 - if (status.error_type == ENUM_ADS_ERROR_KRB5) { - if (status.err.rc == KRB5KDC_ERR_PREAUTH_FAILED) { - return NT_STATUS_LOGON_FAILURE; - } else if (status.err.rc == KRB5_KDC_UNREACH) { - return NT_STATUS_NO_LOGON_SERVERS; - } else if (status.err.rc == KRB5KRB_AP_ERR_SKEW) { - return NT_STATUS_TIME_DIFFERENCE_AT_DC; - } - } + case ENUM_ADS_ERROR_KRB5: + return krb5_to_ntstatus(status.err.rc); #endif - if (ADS_ERR_OK(status)) return NT_STATUS_OK; + default: + break; + } + + if (ADS_ERR_OK(status)) { + return NT_STATUS_OK; + } return NT_STATUS_UNSUCCESSFUL; } -- cgit From f852fdbe06ec9f19424d6870cba9b1872a0d5d7a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Aug 2006 17:55:06 +0000 Subject: r17626: Some C++ Warnings (This used to be commit 09e7c010f03ac3c621f7a7fad44685d278c1481a) --- source3/libads/ads_struct.c | 2 +- source3/libads/krb5_setpw.c | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index 7a03a2a80f..372f72fe06 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -42,7 +42,7 @@ char *ads_build_path(const char *realm, const char *sep, const char *field, int len = (numbits+1)*(strlen(field)+1) + strlen(r) + 1; - ret = SMB_MALLOC(len); + ret = (char *)SMB_MALLOC(len); if (!ret) return NULL; diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 07e6320c26..c7a4b982db 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -667,7 +667,9 @@ kerb_prompter(krb5_context ctx, void *data, memset(prompts[0].reply->data, 0, prompts[0].reply->length); if (prompts[0].reply->length > 0) { if (data) { - strncpy(prompts[0].reply->data, data, prompts[0].reply->length-1); + strncpy(prompts[0].reply->data, + (const char *)data, + prompts[0].reply->length-1); prompts[0].reply->length = strlen(prompts[0].reply->data); } else { prompts[0].reply->length = 0; -- cgit From 58247fea05a7420d8eafa0b8ea03944e9422cb6c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 22 Aug 2006 00:36:31 +0000 Subject: r17677: There is no need for a 2nd krb5_to_nt_status function, is there? Michael Adam/Volker, please check. Guenther (This used to be commit d0feb85781f69325ee70aff98370cfac037c4cc2) --- source3/libads/ads_status.c | 2 +- source3/libads/krb5_errs.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_status.c b/source3/libads/ads_status.c index 00427936ad..07c60c5ac0 100644 --- a/source3/libads/ads_status.c +++ b/source3/libads/ads_status.c @@ -83,7 +83,7 @@ NTSTATUS ads_ntstatus(ADS_STATUS status) #endif #ifdef HAVE_KRB5 case ENUM_ADS_ERROR_KRB5: - return krb5_to_ntstatus(status.err.rc); + return krb5_to_nt_status(status.err.rc); #endif default: break; diff --git a/source3/libads/krb5_errs.c b/source3/libads/krb5_errs.c index e73482522b..38d34f8676 100644 --- a/source3/libads/krb5_errs.c +++ b/source3/libads/krb5_errs.c @@ -55,6 +55,7 @@ static const struct { #if defined(KRB5KRB_ERR_RESPONSE_TOO_BIG) {KRB5KRB_ERR_RESPONSE_TOO_BIG, NT_STATUS_PROTOCOL_UNREACHABLE}, #endif + {KRB5KDC_ERR_NONE, NT_STATUS_OK}, {0, NT_STATUS_OK} }; -- cgit From 8cac7c139908eff0124a4a6f9d25f3b3fe10a254 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 24 Aug 2006 12:13:57 +0000 Subject: r17795: Finally track down the "ads_connect: Interrupted system call" error. Fix our DNS SRV lookup code to deal with multi-homed hosts. We were noly remembering one IP address per host from the Additional records section in the SRV response which could have been an unreachable address. (This used to be commit 899179d2b9fba13cc6f4dab6efc3c22e44e062bc) --- source3/libads/dns.c | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/dns.c b/source3/libads/dns.c index 903d19b753..c946ab0bdd 100644 --- a/source3/libads/dns.c +++ b/source3/libads/dns.c @@ -398,14 +398,45 @@ static NTSTATUS ads_dns_lookup_srv( TALLOC_CTX *ctx, const char *name, struct dn } /* only interested in A records as a shortcut for having to come - back later and lookup the name */ + back later and lookup the name. For multi-homed hosts, the + number of additional records and exceed the number of answer + records. */ + if ( (rr.type != T_A) || (rr.rdatalen != 4) ) continue; + /* FIX ME!!! Should this be a list of IP addresses for + each host? */ + for ( i=0; i Date: Thu, 24 Aug 2006 15:43:32 +0000 Subject: r17798: Beginnings of a standalone libaddns library released under the LGPL. Original code by Krishna Ganugapati . Additional work by me. It's still got some warts, but non-secure updates do currently work. There are at least four things left to really clean up. 1. Change the memory management to use talloc() rather than malloc() and cleanup the leaks. 2. Fix the error code reporting (see initial changes to dnserr.h) 3. Fix the secure updates 4. Define a public interface in addns.h 5. Move the code in libads/dns.c into the libaddns/ directory (and under the LGPL). A few notes: * Enable the new code by compiling with --with-dnsupdate * Also adds the command 'net ads dns register' * Requires -luuid (included in the e2fsprogs-devel package). * Has only been tested on Linux platforms so there may be portability issues. (This used to be commit 36f04674aeefd93c5a0408b8967dcd48b86fdbc1) --- source3/libads/ldap.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 52426c31ae..4f1f0146a7 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2691,18 +2691,18 @@ char* ads_get_upn( ADS_STRUCT *ads, TALLOC_CTX *ctx, const char *machine_name ) status = ads_find_machine_acct(ads, (void **)(void *)&res, global_myname()); if (!ADS_ERR_OK(status)) { - DEBUG(0,("ads_get_dnshostname: Failed to find account for %s\n", + DEBUG(0,("ads_get_upn: Failed to find account for %s\n", global_myname())); goto out; } if ( (count = ads_count_replies(ads, res)) != 1 ) { - DEBUG(1,("ads_get_dnshostname: %d entries returned!\n", count)); + DEBUG(1,("ads_get_upn: %d entries returned!\n", count)); goto out; } if ( (name = ads_pull_string(ads, ctx, res, "userPrincipalName")) == NULL ) { - DEBUG(0,("ads_get_dnshostname: No userPrincipalName attribute!\n")); + DEBUG(2,("ads_get_upn: No userPrincipalName attribute!\n")); } out: -- cgit From 4bbb995e8dab284b4deaa2e2ee38eb329305d1c2 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 27 Aug 2006 17:24:31 +0000 Subject: r17854: Steal the LDAP in NTSTATUS trick from Samba4 Thanks to Michael Adam Volker (This used to be commit 91878f9b6fbe5187fb7d0464008ea0abe7f11a73) --- source3/libads/ads_status.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_status.c b/source3/libads/ads_status.c index 07c60c5ac0..111a52e072 100644 --- a/source3/libads/ads_status.c +++ b/source3/libads/ads_status.c @@ -76,10 +76,7 @@ NTSTATUS ads_ntstatus(ADS_STATUS status) return map_nt_error_from_unix(status.err.rc); #ifdef HAVE_LDAP case ENUM_ADS_ERROR_LDAP: - if (status.err.rc == LDAP_NO_MEMORY) { - return NT_STATUS_NO_MEMORY; - } - break; + return NT_STATUS_LDAP(status.err.rc); #endif #ifdef HAVE_KRB5 case ENUM_ADS_ERROR_KRB5: -- cgit From c52b3fb89f29110d2c2026a540e5dd39826bb799 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 28 Aug 2006 09:19:30 +0000 Subject: r17881: Another microstep towards better error reporting: Make get_sorted_dc_list return NTSTATUS. If we want to differentiate different name resolution problems we might want to introduce yet another error class for Samba-internal errors. Things like no route to host to the WINS server, a DNS server explicitly said host not found etc might be worth passing up. Because we can not stash everything into the existing NT_STATUS codes, what about a Samba-specific error class like NT_STATUS_DOS and NT_STATUS_LDAP? Volker (This used to be commit 60a166f0347170dff38554bed46193ce1226c8c1) --- source3/libads/ldap.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 4f1f0146a7..402e37b3c0 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -182,7 +182,7 @@ BOOL ads_try_connect(ADS_STRUCT *ads, const char *server ) disabled **********************************************************************/ -static BOOL ads_find_dc(ADS_STRUCT *ads) +static NTSTATUS ads_find_dc(ADS_STRUCT *ads) { const char *c_realm; int count, i=0; @@ -190,6 +190,7 @@ static BOOL ads_find_dc(ADS_STRUCT *ads) pstring realm; BOOL got_realm = False; BOOL use_own_domain = False; + NTSTATUS status = NT_STATUS_UNSUCCESSFUL; /* if the realm and workgroup are both empty, assume they are ours */ @@ -220,7 +221,7 @@ again: if ( !c_realm || !*c_realm ) { DEBUG(0,("ads_find_dc: no realm or workgroup! Don't know what to do\n")); - return False; + return NT_STATUS_INVALID_PARAMETER; /* rather need MISSING_PARAMETER ... */ } } @@ -229,14 +230,15 @@ again: DEBUG(6,("ads_find_dc: looking for %s '%s'\n", (got_realm ? "realm" : "domain"), realm)); - if ( !get_sorted_dc_list(realm, &ip_list, &count, got_realm) ) { + status = get_sorted_dc_list(realm, &ip_list, &count, got_realm); + if (!NT_STATUS_IS_OK(status)) { /* fall back to netbios if we can */ if ( got_realm && !lp_disable_netbios() ) { got_realm = False; goto again; } - return False; + return status; } /* if we fail this loop, then giveup since all the IP addresses returned were dead */ @@ -250,7 +252,7 @@ again: if ( ads_try_connect(ads, server) ) { SAFE_FREE(ip_list); - return True; + return NT_STATUS_OK; } /* keep track of failures */ @@ -259,7 +261,7 @@ again: SAFE_FREE(ip_list); - return False; + return NT_STATUS_NO_LOGON_SERVERS; } @@ -272,6 +274,7 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) { int version = LDAP_VERSION3; ADS_STATUS status; + NTSTATUS ntstatus; ads->last_attempt = time(NULL); ads->ld = NULL; @@ -283,11 +286,12 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) goto got_connection; } - if (ads_find_dc(ads)) { + ntstatus = ads_find_dc(ads); + if (NT_STATUS_IS_OK(ntstatus)) { goto got_connection; } - return ADS_ERROR_NT(NT_STATUS_NO_LOGON_SERVERS); + return ADS_ERROR_NT(ntstatus); got_connection: DEBUG(3,("Connected to LDAP server %s\n", inet_ntoa(ads->ldap_ip))); -- cgit From 0362fde476733bacfd7aa2d5eba24597a7f4fd56 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 29 Aug 2006 00:53:28 +0000 Subject: r17899: Fix Stanford checker bug - possible null deref. Jeremy. (This used to be commit e77949175144cbe4cfa58788d13acc704eebc251) --- source3/libads/sasl.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 3c0bea93d6..b2613071b7 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -276,7 +276,7 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) int i=0; int gss_rc, rc; uint8 *p; - uint32 max_msg_size; + uint32 max_msg_size = 0; char *sname; ADS_STATUS status; krb5_principal principal; @@ -389,7 +389,10 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) #if 0 file_save("sasl_gssapi.dat", output_token.value, output_token.length); #endif - max_msg_size = (p[1]<<16) | (p[2]<<8) | p[3]; + + if (p) { + max_msg_size = (p[1]<<16) | (p[2]<<8) | p[3]; + } gss_release_buffer(&minor_status, &output_token); -- cgit From 9f0c2827a4e08cb386453d1ce740f4b559b557fd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 29 Aug 2006 01:04:25 +0000 Subject: r17901: Stanford checker fix. cookie here can't be null or we'd deref null. Make interface explicit. Jeremy. (This used to be commit 4e99606ec16b978a76219b5362a23a7b06ee5468) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 402e37b3c0..c6d1fc9c60 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -506,7 +506,7 @@ ADS_STATUS ads_do_paged_search_args(ADS_STRUCT *ads, const char *bind_path, } cookie_be = ber_alloc_t(LBER_USE_DER); - if (cookie && *cookie) { + if (*cookie) { ber_printf(cookie_be, "{iO}", (ber_int_t) 1000, *cookie); ber_bvfree(*cookie); /* don't need it from last time */ *cookie = NULL; -- cgit From 743a8e7f005762d4c5740d18b956636cbb6213e8 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 29 Aug 2006 15:43:15 +0000 Subject: r17910: remove incorrect comment (code has already been fixed) (This used to be commit 9810d74e171542408eea3ec22a0ebb57a9e1e87e) --- source3/libads/dns.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/dns.c b/source3/libads/dns.c index c946ab0bdd..8cc68a0c14 100644 --- a/source3/libads/dns.c +++ b/source3/libads/dns.c @@ -406,9 +406,6 @@ static NTSTATUS ads_dns_lookup_srv( TALLOC_CTX *ctx, const char *name, struct dn if ( (rr.type != T_A) || (rr.rdatalen != 4) ) continue; - /* FIX ME!!! Should this be a list of IP addresses for - each host? */ - for ( i=0; i Date: Wed, 30 Aug 2006 04:40:03 +0000 Subject: r17928: Implement the basic store for CLDAP sitename support when looking up DC's. On every CLDAP call store the returned client sitename (if present, delete store if not) in gencache with infinate timeout. On AD DNS DC lookup, try looking for sitename DC's first, only try generic if sitename DNS lookup failed. I still haven't figured out yet how to ensure we fetch the sitename with a CLDAP query before doing the generic DC list lookup. This code is difficult to understand. I'll do some experiments and backtraces tomorrow to try and work out where to force a CLDAP site query first. Jeremy. (This used to be commit ab3f0c5b1e9c5fd192c5514cbe9451b938f9cd5d) --- source3/libads/cldap.c | 4 +- source3/libads/dns.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++--- source3/libads/ldap.c | 3 ++ 3 files changed, 99 insertions(+), 7 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/cldap.c b/source3/libads/cldap.c index 2e96270e90..3a6083558f 100644 --- a/source3/libads/cldap.c +++ b/source3/libads/cldap.c @@ -260,8 +260,8 @@ static int recv_cldap_netlogon(int sock, struct cldap_netlogon_reply *reply) *reply->user_name = 0; } - p += pull_netlogon_string(reply->site_name, p, (const char *)os3.data); - p += pull_netlogon_string(reply->site_name_2, p, (const char *)os3.data); + p += pull_netlogon_string(reply->server_site_name, p, (const char *)os3.data); + p += pull_netlogon_string(reply->client_site_name, p, (const char *)os3.data); reply->version = IVAL(p, 0); reply->lmnt_token = SVAL(p, 4); diff --git a/source3/libads/dns.c b/source3/libads/dns.c index 8cc68a0c14..937cd9213f 100644 --- a/source3/libads/dns.c +++ b/source3/libads/dns.c @@ -565,16 +565,105 @@ NTSTATUS ads_dns_lookup_ns( TALLOC_CTX *ctx, const char *dnsdomain, struct dns_r return NT_STATUS_OK; } +/**************************************************************************** + Store and fetch the AD client sitename. +****************************************************************************/ -/******************************************************************** -********************************************************************/ +#define SITENAME_KEY "AD_SITENAME" + +/**************************************************************************** + Store the AD client sitename. + We store indefinately as every new CLDAP query will re-write this. +****************************************************************************/ -NTSTATUS ads_dns_query_dcs( TALLOC_CTX *ctx, const char *domain, struct dns_rr_srv **dclist, int *numdcs ) +BOOL sitename_store(const char *sitename) { - pstring name; + time_t expire; + BOOL ret = False; + + if ( !sitename || (sitename && !*sitename)) { + DEBUG(2,("sitename_store: deleting empty sitename!\n")); + return gencache_del(SITENAME_KEY); + } + + if (!gencache_init()) { + return False; + } + + expire = get_time_t_max(); /* Store indefinately. */ + + DEBUG(10,("sitename_store: sitename = [%s], expire = [%u]\n", + sitename, (unsigned int)expire )); + + ret = gencache_set( SITENAME_KEY, sitename, expire ); + return ret; +} - snprintf( name, sizeof(name), "_ldap._tcp.dc._msdcs.%s", domain ); +/**************************************************************************** + Fetch the AD client sitename. + Caller must free. +****************************************************************************/ +static char *sitename_fetch(void) +{ + char *sitename = NULL; + time_t timeout; + BOOL ret = False; + + if (!gencache_init()) { + return False; + } + + ret = gencache_get( SITENAME_KEY, &sitename, &timeout ); + if ( !ret ) { + DEBUG(5,("sitename_fetch: No stored sitename\n")); + } else { + DEBUG(5,("sitename_fetch: Returning sitename \"%s\"\n", + sitename )); + } + return sitename; +} + +/******************************************************************** + Query with optional sitename. +********************************************************************/ + +NTSTATUS ads_dns_query_dcs_internal(TALLOC_CTX *ctx, + const char *domain, + const char *sitename, + struct dns_rr_srv **dclist, + int *numdcs ) +{ + char *name; + if (sitename) { + name = talloc_asprintf(ctx, "_ldap._tcp.%s._sites.dc._msdcs.%s", + sitename, domain ); + } else { + name = talloc_asprintf(ctx, "_ldap._tcp.dc._msdcs.%s", domain ); + } + if (!name) { + return NT_STATUS_NO_MEMORY; + } return ads_dns_lookup_srv( ctx, name, dclist, numdcs ); } +/******************************************************************** + Query for AD DC's. Transparently use sitename. +********************************************************************/ + +NTSTATUS ads_dns_query_dcs(TALLOC_CTX *ctx, + const char *domain, + struct dns_rr_srv **dclist, + int *numdcs ) +{ + NTSTATUS status; + char *sitename = sitename_fetch(); + + status = ads_dns_query_dcs_internal(ctx, domain, sitename, dclist, numdcs); + if (sitename && !NT_STATUS_IS_OK(status)) { + /* Sitename DNS query may have failed. Try without. */ + status = ads_dns_query_dcs_internal(ctx, domain, NULL, dclist, numdcs); + } + SAFE_FREE(sitename); + return status; +} diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index c6d1fc9c60..c943558bd3 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -173,6 +173,9 @@ BOOL ads_try_connect(ADS_STRUCT *ads, const char *server ) saf_store( ads->server.workgroup, server ); + /* Store our site name. */ + sitename_store( cldap_reply.client_site_name ); + return True; } -- cgit From 7b7ce43b40888af7d2663e77d8a9e83c383c6b2d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 30 Aug 2006 05:52:31 +0000 Subject: r17929: Ok, I think I finally figured out where to put the code to redo the CLDAP query to restrict DC DNS lookups to the sitename. Jerry, please check to stop me going insane :-). Jeremy. (This used to be commit 8d22cc111579c57aec65be8884b41564b79b133a) --- source3/libads/dns.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/dns.c b/source3/libads/dns.c index 937cd9213f..430486741d 100644 --- a/source3/libads/dns.c +++ b/source3/libads/dns.c @@ -604,7 +604,7 @@ BOOL sitename_store(const char *sitename) Caller must free. ****************************************************************************/ -static char *sitename_fetch(void) +char *sitename_fetch(void) { char *sitename = NULL; time_t timeout; @@ -624,6 +624,25 @@ static char *sitename_fetch(void) return sitename; } +/**************************************************************************** + Did the sitename change ? +****************************************************************************/ + +BOOL sitename_changed(const char *sitename) +{ + BOOL ret = False; + char *new_sitename = sitename_fetch(); + + if (sitename && new_sitename && !strequal(sitename, new_sitename)) { + ret = True; + } else if ((sitename && !new_sitename) || + (!sitename && new_sitename)) { + ret = True; + } + SAFE_FREE(new_sitename); + return ret; +} + /******************************************************************** Query with optional sitename. ********************************************************************/ -- cgit From 9d37ee52e0d616b60e6644050d259e884ee5870d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 30 Aug 2006 18:48:49 +0000 Subject: r17937: Move the saf_ cache into the tcp ad connection code. Cause winbindd to set site support before doing the generic AD server lookup. Jeremy. (This used to be commit a9833941715472ece747bce69ef53ba8ad98d7a5) --- source3/libads/ldap.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index c943558bd3..947f58a8fd 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -169,10 +169,6 @@ BOOL ads_try_connect(ADS_STRUCT *ads, const char *server ) ads->ldap_ip = *interpret_addr2(srv); SAFE_FREE(srv); - /* cache the successful connection */ - - saf_store( ads->server.workgroup, server ); - /* Store our site name. */ sitename_store( cldap_reply.client_site_name ); @@ -243,7 +239,7 @@ again: return status; } - + /* if we fail this loop, then giveup since all the IP addresses returned were dead */ for ( i=0; iserver.workgroup, inet_ntoa(ads->ldap_ip)); + ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); status = ADS_ERROR(smb_ldap_start_tls(ads->ld, version)); -- cgit From 256172f7d6dd384ea95457dd6322e0289057ac56 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 31 Aug 2006 00:07:24 +0000 Subject: r17942: Jerry is right - when no site support is enabled the client sitename is "Default-First-Site-Name". Treat this as a blank site (no site configured). Jeremy. (This used to be commit 5c46381bd7dd1b3f11f427d111ded0b76fc1bec8) --- source3/libads/dns.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/dns.c b/source3/libads/dns.c index 430486741d..4d935c1b6e 100644 --- a/source3/libads/dns.c +++ b/source3/libads/dns.c @@ -574,22 +574,27 @@ NTSTATUS ads_dns_lookup_ns( TALLOC_CTX *ctx, const char *dnsdomain, struct dns_r /**************************************************************************** Store the AD client sitename. We store indefinately as every new CLDAP query will re-write this. + If the sitename is "Default-First-Site-Name" we don't store it + as this isn't a valid DNS name. ****************************************************************************/ BOOL sitename_store(const char *sitename) { time_t expire; BOOL ret = False; - - if ( !sitename || (sitename && !*sitename)) { - DEBUG(2,("sitename_store: deleting empty sitename!\n")); - return gencache_del(SITENAME_KEY); - } - + if (!gencache_init()) { return False; } + if (!sitename || (sitename && !*sitename)) { + DEBUG(5,("sitename_store: deleting empty sitename!\n")); + return gencache_del(SITENAME_KEY); + } else if (sitename && strequal(sitename, "Default-First-Site-Name")) { + DEBUG(5,("sitename_store: delete default sitename Default-First-Site-Name\n")); + return gencache_del(SITENAME_KEY); + } + expire = get_time_t_max(); /* Store indefinately. */ DEBUG(10,("sitename_store: sitename = [%s], expire = [%u]\n", -- cgit From 6fada7a82aa67e7b80ff003bd527092da68542c8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 31 Aug 2006 01:20:21 +0000 Subject: r17943: The horror, the horror. Add KDC site support by writing out a custom krb5.conf file containing the KDC I need. This may suck.... Needs some testing :-). Jeremy. (This used to be commit d500e1f96d92dfcc6292c448d1b399195f762d89) --- source3/libads/cldap.c | 2 -- source3/libads/kerberos.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++ source3/libads/ldap.c | 1 + 3 files changed, 59 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/cldap.c b/source3/libads/cldap.c index 3a6083558f..da1dec6b93 100644 --- a/source3/libads/cldap.c +++ b/source3/libads/cldap.c @@ -306,5 +306,3 @@ BOOL ads_cldap_netlogon(const char *server, const char *realm, struct cldap_net return True; } - - diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 910207968c..4e4e4cfebf 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -464,4 +464,62 @@ int kerberos_kinit_password(const char *principal, 0); } +/************************************************************************ + Create a specific krb5.conf file in the private directory pointing + at a specific kdc for a realm. Keyed off domain name. Sets + KRB5_CONFIG environment variable to point to this file. Must be + run as root or will fail (which is a good thing :-). +************************************************************************/ + +BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *domain, struct in_addr ip) +{ + XFILE *xfp = NULL; + char *fname = talloc_asprintf(NULL, "%s/smb_krb5.conf.%s", lp_private_dir(), domain); + char *file_contents = NULL; + size_t flen = 0; + + if (!fname) { + return False; + } + + file_contents = talloc_asprintf(fname, "[libdefaults]\n\tdefault_realm = %s\n" + "[realms]\n\t%s = {\n" + "\t\tkdc = %s\n]\n", + realm, realm, inet_ntoa(ip)); + + if (!file_contents) { + TALLOC_FREE(fname); + return False; + } + + flen = strlen(file_contents); + xfp = x_fopen(fname, O_CREAT|O_WRONLY, 0600); + if (!xfp) { + TALLOC_FREE(fname); + return False; + } + /* Lock the file. */ + if (!fcntl_lock(xfp->fd, F_SETLKW, 0, 1, F_WRLCK)) { + unlink(fname); + x_fclose(xfp); + TALLOC_FREE(fname); + return False; + } + + if (x_fwrite(file_contents, flen, 1, xfp) != flen) { + unlink(fname); + x_fclose(xfp); + TALLOC_FREE(fname); + return False; + } + if (x_fclose(xfp)==-1) { + unlink(fname); + TALLOC_FREE(fname); + return False; + } + /* Set the environment variable to this file. */ + setenv("KRB5_CONFIG", fname, 1); + TALLOC_FREE(fname); + return True; +} #endif diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 947f58a8fd..1d192895d9 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -159,6 +159,7 @@ BOOL ads_try_connect(ADS_STRUCT *ads, const char *server ) SAFE_FREE(ads->config.ldap_server_name); SAFE_FREE(ads->server.workgroup); + ads->config.flags = cldap_reply.flags; ads->config.ldap_server_name = SMB_STRDUP(cldap_reply.hostname); strupper_m(cldap_reply.domain); ads->config.realm = SMB_STRDUP(cldap_reply.domain); -- cgit From cceb492250ce7e273cdc48c030048c0879a7265a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 31 Aug 2006 01:27:51 +0000 Subject: r17944: Handle locking madness. Jeremy. (This used to be commit 408267a2d725a0596be37b019fe4513502b2c0ec) --- source3/libads/kerberos.c | 43 ++++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 11 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 4e4e4cfebf..46b64ca22d 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -477,6 +477,7 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do char *fname = talloc_asprintf(NULL, "%s/smb_krb5.conf.%s", lp_private_dir(), domain); char *file_contents = NULL; size_t flen = 0; + int loopcount = 0; if (!fname) { return False; @@ -493,17 +494,37 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do } flen = strlen(file_contents); - xfp = x_fopen(fname, O_CREAT|O_WRONLY, 0600); - if (!xfp) { - TALLOC_FREE(fname); - return False; - } - /* Lock the file. */ - if (!fcntl_lock(xfp->fd, F_SETLKW, 0, 1, F_WRLCK)) { - unlink(fname); - x_fclose(xfp); - TALLOC_FREE(fname); - return False; + + while (loopcount < 10) { + SMB_STRUCT_STAT st; + + xfp = x_fopen(fname, O_CREAT|O_WRONLY, 0600); + if (!xfp) { + TALLOC_FREE(fname); + return False; + } + /* Lock the file. */ + if (!fcntl_lock(xfp->fd, F_SETLKW, 0, 1, F_WRLCK)) { + unlink(fname); + x_fclose(xfp); + TALLOC_FREE(fname); + return False; + } + + /* We got the lock. Is the file still there ? */ + if (sys_stat(fname,&st)==-1) { + if (errno == ENOENT) { + /* Nope - try again up to 10x */ + x_fclose(xfp); + loopcount++; + continue; + } + unlink(fname); + x_fclose(xfp); + TALLOC_FREE(fname); + return False; + } + break; } if (x_fwrite(file_contents, flen, 1, xfp) != flen) { -- cgit From 2fcd113f5507f643fcf80d5a9770ce72aa121ba8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 31 Aug 2006 04:14:08 +0000 Subject: r17945: Store the server and client sitenames in the ADS struct so we can see when they match - only create the ugly krb5 hack when they do. Jeremy. (This used to be commit 9be4ecf24b6b5dacf4c2891bddb072fa7543753f) --- source3/libads/ads_struct.c | 2 ++ source3/libads/dns.c | 12 +++++++++--- source3/libads/kerberos.c | 11 ++++++++++- source3/libads/ldap.c | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 53 insertions(+), 4 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index 372f72fe06..130d86b8dc 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -136,6 +136,8 @@ void ads_destroy(ADS_STRUCT **ads) SAFE_FREE((*ads)->config.realm); SAFE_FREE((*ads)->config.bind_path); SAFE_FREE((*ads)->config.ldap_server_name); + SAFE_FREE((*ads)->config.server_site_name); + SAFE_FREE((*ads)->config.client_site_name); SAFE_FREE((*ads)->schema.posix_uidnumber_attr); SAFE_FREE((*ads)->schema.posix_gidnumber_attr); diff --git a/source3/libads/dns.c b/source3/libads/dns.c index 4d935c1b6e..3f99a73a33 100644 --- a/source3/libads/dns.c +++ b/source3/libads/dns.c @@ -590,8 +590,9 @@ BOOL sitename_store(const char *sitename) if (!sitename || (sitename && !*sitename)) { DEBUG(5,("sitename_store: deleting empty sitename!\n")); return gencache_del(SITENAME_KEY); - } else if (sitename && strequal(sitename, "Default-First-Site-Name")) { - DEBUG(5,("sitename_store: delete default sitename Default-First-Site-Name\n")); + } else if (sitename && strequal(sitename, DEFAULT_SITE_NAME)) { + DEBUG(5,("sitename_store: delete default sitename %s\n", + DEFAULT_SITE_NAME)); return gencache_del(SITENAME_KEY); } @@ -633,11 +634,16 @@ char *sitename_fetch(void) Did the sitename change ? ****************************************************************************/ -BOOL sitename_changed(const char *sitename) +BOOL stored_sitename_changed(const char *sitename) { BOOL ret = False; char *new_sitename = sitename_fetch(); + /* Treat default site as no name. */ + if (strequal(sitename, DEFAULT_SITE_NAME)) { + sitename = NULL; + } + if (sitename && new_sitename && !strequal(sitename, new_sitename)) { ret = True; } else if ((sitename && !new_sitename) || diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 46b64ca22d..dc85a77304 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -477,16 +477,20 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do char *fname = talloc_asprintf(NULL, "%s/smb_krb5.conf.%s", lp_private_dir(), domain); char *file_contents = NULL; size_t flen = 0; + char *realm_upper = NULL; int loopcount = 0; if (!fname) { return False; } + realm_upper = talloc_strdup(fname, realm); + strupper_m(realm_upper); + file_contents = talloc_asprintf(fname, "[libdefaults]\n\tdefault_realm = %s\n" "[realms]\n\t%s = {\n" "\t\tkdc = %s\n]\n", - realm, realm, inet_ntoa(ip)); + realm_upper, realm_upper, inet_ntoa(ip)); if (!file_contents) { TALLOC_FREE(fname); @@ -541,6 +545,11 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do /* Set the environment variable to this file. */ setenv("KRB5_CONFIG", fname, 1); TALLOC_FREE(fname); + + DEBUG(5,("create_local_private_krb5_conf_for_domain: wrote " + "file %s with realm %s KDC = %s\n", + realm_upper, inet_ntoa(ip)); + return True; } #endif diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 1d192895d9..60e4c9f5b7 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -115,6 +115,27 @@ static int ldap_search_with_timeout(LDAP *ld, return result; } +#ifdef HAVE_KRB5 +/********************************************** + Do client and server sitename match ? +**********************************************/ + +BOOL ads_sitename_match(ADS_STRUCT *ads) +{ + if (ads->config.server_site_name == NULL && + ads->config.client_site_name == NULL ) { + return True; + } + if (ads->config.server_site_name && + ads->config.client_site_name && + strequal(ads->config.server_site_name, + ads->config.client_site_name)) { + return True; + } + return False; +} +#endif + /* try a connection to a given ldap server, returning True and setting the servers IP in the ads struct if successful @@ -157,6 +178,8 @@ BOOL ads_try_connect(ADS_STRUCT *ads, const char *server ) SAFE_FREE(ads->config.realm); SAFE_FREE(ads->config.bind_path); SAFE_FREE(ads->config.ldap_server_name); + SAFE_FREE(ads->config.server_site); + SAFE_FREE(ads->config.client_site); SAFE_FREE(ads->server.workgroup); ads->config.flags = cldap_reply.flags; @@ -164,6 +187,15 @@ BOOL ads_try_connect(ADS_STRUCT *ads, const char *server ) strupper_m(cldap_reply.domain); ads->config.realm = SMB_STRDUP(cldap_reply.domain); ads->config.bind_path = ads_build_dn(ads->config.realm); + if (*cldap_reply.server_site_name) { + ads->config.server_site_name = + SMB_STRDUP(cldap_reply.server_site_name); + } + if (*cldap_reply.client_site_name) { + ads->config.server_site_name = + SMB_STRDUP(cldap_reply.server_site_name); + } + ads->server.workgroup = SMB_STRDUP(cldap_reply.netbios_domain); ads->ldap_port = LDAP_PORT; -- cgit From a78c61b9cdb535d43cda6de038ec7718e8b24491 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 31 Aug 2006 04:16:13 +0000 Subject: r17946: Fix couple of typos... Jeremy. (This used to be commit 638d53e2ad524dfe4666b79d36997dea8a44c8cd) --- source3/libads/kerberos.c | 2 +- source3/libads/ldap.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index dc85a77304..0707427a22 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -548,7 +548,7 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do DEBUG(5,("create_local_private_krb5_conf_for_domain: wrote " "file %s with realm %s KDC = %s\n", - realm_upper, inet_ntoa(ip)); + fname, realm_upper, inet_ntoa(ip) )); return True; } diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 60e4c9f5b7..4fbb0c7af3 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -178,8 +178,8 @@ BOOL ads_try_connect(ADS_STRUCT *ads, const char *server ) SAFE_FREE(ads->config.realm); SAFE_FREE(ads->config.bind_path); SAFE_FREE(ads->config.ldap_server_name); - SAFE_FREE(ads->config.server_site); - SAFE_FREE(ads->config.client_site); + SAFE_FREE(ads->config.server_site_name); + SAFE_FREE(ads->config.client_site_name); SAFE_FREE(ads->server.workgroup); ads->config.flags = cldap_reply.flags; -- cgit From 305ceade3905dad45eac2f407dd8f56a9979cf1c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 31 Aug 2006 16:26:32 +0000 Subject: r17970: Add missing include-guards around ads.h and ads_cldap.h. Remove all reference to "Default-First-Site-Name" and treat it like any other site. Jeremy. (This used to be commit 5ae3564d6844f44a6943b2028917bd457371af1e) --- source3/libads/dns.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/dns.c b/source3/libads/dns.c index 3f99a73a33..579296ea1f 100644 --- a/source3/libads/dns.c +++ b/source3/libads/dns.c @@ -590,10 +590,6 @@ BOOL sitename_store(const char *sitename) if (!sitename || (sitename && !*sitename)) { DEBUG(5,("sitename_store: deleting empty sitename!\n")); return gencache_del(SITENAME_KEY); - } else if (sitename && strequal(sitename, DEFAULT_SITE_NAME)) { - DEBUG(5,("sitename_store: delete default sitename %s\n", - DEFAULT_SITE_NAME)); - return gencache_del(SITENAME_KEY); } expire = get_time_t_max(); /* Store indefinately. */ @@ -639,11 +635,6 @@ BOOL stored_sitename_changed(const char *sitename) BOOL ret = False; char *new_sitename = sitename_fetch(); - /* Treat default site as no name. */ - if (strequal(sitename, DEFAULT_SITE_NAME)) { - sitename = NULL; - } - if (sitename && new_sitename && !strequal(sitename, new_sitename)) { ret = True; } else if ((sitename && !new_sitename) || -- cgit From e53dfa1f4a1162b814ea7dc23c7c603d1c6c4908 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 31 Aug 2006 18:32:23 +0000 Subject: r17971: Disable storing SIDs in the S-1-22-1 and S-1-22-2 domain to the SID<->uid/gid cache. FIxes a bug in token creation (This used to be commit fa05708789654a8a34cb4a4068514a0b3d950653) --- source3/libads/kerberos_verify.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 3aa0860809..cff007db47 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -376,13 +376,15 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, goto out; } - if (lp_use_kerberos_keytab()) { + /* always check secrets first in order to prevent hitting the + keytab until really necessary */ + + auth_ok = ads_secrets_verify_ticket(context, auth_context, host_princ, + ticket, &packet, &tkt, &keyblock); + + if (!auth_ok && lp_use_kerberos_keytab()) { auth_ok = ads_keytab_verify_ticket(context, auth_context, ticket, &packet, &tkt, &keyblock); } - if (!auth_ok) { - auth_ok = ads_secrets_verify_ticket(context, auth_context, host_princ, - ticket, &packet, &tkt, &keyblock); - } release_server_mutex(); got_replay_mutex = False; -- cgit From ac25c32322d69cf3e125c5d84766d9a3f70a4e89 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 31 Aug 2006 18:33:50 +0000 Subject: r17972: revert accidental commit to ads_verify_ticket() (This used to be commit 95f6b22e5179e1fb738c07112de2e06024fc9a83) --- source3/libads/kerberos_verify.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index cff007db47..3aa0860809 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -376,15 +376,13 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, goto out; } - /* always check secrets first in order to prevent hitting the - keytab until really necessary */ - - auth_ok = ads_secrets_verify_ticket(context, auth_context, host_princ, - ticket, &packet, &tkt, &keyblock); - - if (!auth_ok && lp_use_kerberos_keytab()) { + if (lp_use_kerberos_keytab()) { auth_ok = ads_keytab_verify_ticket(context, auth_context, ticket, &packet, &tkt, &keyblock); } + if (!auth_ok) { + auth_ok = ads_secrets_verify_ticket(context, auth_context, host_princ, + ticket, &packet, &tkt, &keyblock); + } release_server_mutex(); got_replay_mutex = False; -- cgit From 0c9ca3fe19249c19ac3525f3e6e19242b3e77f7f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 2 Sep 2006 01:23:08 +0000 Subject: r17994: Add debugs that showed me why my site code wasn't working right. Don't update the server site when we have a client one... Jeremy. (This used to be commit 7acbcf9a6c71f8e7f9167880488613c930cef4d9) --- source3/libads/kerberos.c | 3 +++ source3/libads/ldap.c | 9 +++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 0707427a22..fb15ace7c7 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -484,6 +484,9 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do return False; } + DEBUG(10,("create_local_private_krb5_conf_for_domain: fname = %s, realm = %s, domain = %s\n", + fname, realm, domain )); + realm_upper = talloc_strdup(fname, realm); strupper_m(realm_upper); diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 4fbb0c7af3..b23bc277e8 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -124,14 +124,19 @@ BOOL ads_sitename_match(ADS_STRUCT *ads) { if (ads->config.server_site_name == NULL && ads->config.client_site_name == NULL ) { + DEBUG(10,("ads_sitename_match: both null\n")); return True; } if (ads->config.server_site_name && ads->config.client_site_name && strequal(ads->config.server_site_name, ads->config.client_site_name)) { + DEBUG(10,("ads_sitename_match: name %s match\n", ads->config.server_site_name)); return True; } + DEBUG(10,("ads_sitename_match: no match %s %s\n", + ads->config.server_site_name ? ads->config.server_site_name : "NULL", + ads->config.client_site_name ? ads->config.client_site_name : "NULL")); return False; } #endif @@ -192,8 +197,8 @@ BOOL ads_try_connect(ADS_STRUCT *ads, const char *server ) SMB_STRDUP(cldap_reply.server_site_name); } if (*cldap_reply.client_site_name) { - ads->config.server_site_name = - SMB_STRDUP(cldap_reply.server_site_name); + ads->config.client_site_name = + SMB_STRDUP(cldap_reply.client_site_name); } ads->server.workgroup = SMB_STRDUP(cldap_reply.netbios_domain); -- cgit From fc6bce6d9ccd5c56ef0bb7c936a724651ef05c4e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 2 Sep 2006 01:33:13 +0000 Subject: r17995: Ensure we create the domain-specific krb5 files in a separate directory. Jeremy. (This used to be commit 541594153b3a29a4ca30f1897264f2cc715b0698) --- source3/libads/kerberos.c | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index fb15ace7c7..80bc5a6661 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -474,13 +474,27 @@ int kerberos_kinit_password(const char *principal, BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *domain, struct in_addr ip) { XFILE *xfp = NULL; - char *fname = talloc_asprintf(NULL, "%s/smb_krb5.conf.%s", lp_private_dir(), domain); + char *dname = talloc_asprintf(NULL, "%s/smb_krb5", lp_private_dir()); + char *fname = NULL; char *file_contents = NULL; size_t flen = 0; char *realm_upper = NULL; int loopcount = 0; + if (!dname) { + return False; + } + if (mkdir(dname, 0700)==-1) { + DEBUG(0,("create_local_private_krb5_conf_for_domain: " + "failed to create directory %s. Error was %s\n", + dname, strerror(errno) )); + TALLOC_FREE(dname); + return False; + } + + fname = talloc_asprintf(dname, "%s/krb5.conf.%s", dname, domain); if (!fname) { + TALLOC_FREE(dname); return False; } @@ -496,7 +510,7 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do realm_upper, realm_upper, inet_ntoa(ip)); if (!file_contents) { - TALLOC_FREE(fname); + TALLOC_FREE(dname); return False; } @@ -507,14 +521,14 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do xfp = x_fopen(fname, O_CREAT|O_WRONLY, 0600); if (!xfp) { - TALLOC_FREE(fname); + TALLOC_FREE(dname); return False; } /* Lock the file. */ if (!fcntl_lock(xfp->fd, F_SETLKW, 0, 1, F_WRLCK)) { unlink(fname); x_fclose(xfp); - TALLOC_FREE(fname); + TALLOC_FREE(dname); return False; } @@ -528,7 +542,7 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do } unlink(fname); x_fclose(xfp); - TALLOC_FREE(fname); + TALLOC_FREE(dname); return False; } break; @@ -537,17 +551,17 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do if (x_fwrite(file_contents, flen, 1, xfp) != flen) { unlink(fname); x_fclose(xfp); - TALLOC_FREE(fname); + TALLOC_FREE(dname); return False; } if (x_fclose(xfp)==-1) { unlink(fname); - TALLOC_FREE(fname); + TALLOC_FREE(dname); return False; } /* Set the environment variable to this file. */ setenv("KRB5_CONFIG", fname, 1); - TALLOC_FREE(fname); + TALLOC_FREE(dname); DEBUG(5,("create_local_private_krb5_conf_for_domain: wrote " "file %s with realm %s KDC = %s\n", -- cgit From ef92f91cd7fa7c6dfa3c805882083c951cb3add6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 2 Sep 2006 01:34:37 +0000 Subject: r17996: Don't talloc free the memory then reference it. Doh ! Jeremy. (This used to be commit 188eb9794df265e8a55602d46b6bb4bd7daffa7f) --- source3/libads/kerberos.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 80bc5a6661..4ddbf0abc5 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -559,14 +559,15 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do TALLOC_FREE(dname); return False; } - /* Set the environment variable to this file. */ - setenv("KRB5_CONFIG", fname, 1); - TALLOC_FREE(dname); DEBUG(5,("create_local_private_krb5_conf_for_domain: wrote " "file %s with realm %s KDC = %s\n", fname, realm_upper, inet_ntoa(ip) )); + /* Set the environment variable to this file. */ + setenv("KRB5_CONFIG", fname, 1); + TALLOC_FREE(dname); + return True; } #endif -- cgit From d62c3cff518ffd701b967bb12b487f097b550c38 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 2 Sep 2006 02:04:41 +0000 Subject: r17997: Ensure lockdir exists for winbindd. Store tmp krb5.conf files under lockdir, not privatedir. Jeremy. (This used to be commit c59eff3e53f5bfae3a9fb136e8566628339863ad) --- source3/libads/kerberos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 4ddbf0abc5..a077ce1fce 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -474,7 +474,7 @@ int kerberos_kinit_password(const char *principal, BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *domain, struct in_addr ip) { XFILE *xfp = NULL; - char *dname = talloc_asprintf(NULL, "%s/smb_krb5", lp_private_dir()); + char *dname = talloc_asprintf(NULL, "%s/smb_krb5", lp_lockdir()); char *fname = NULL; char *file_contents = NULL; size_t flen = 0; -- cgit From 1bd715d9155428afee678fd202483e519820c6df Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 2 Sep 2006 03:42:55 +0000 Subject: r17999: No need to prevent others from reading. Use 755 instead of 700, and 644 instead of 600. Reading might help debugging. Jeremy. (This used to be commit 99f100cfecb53e00d17f7426251a3d4022db791a) --- source3/libads/kerberos.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index a077ce1fce..79196f87a7 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -484,7 +484,7 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do if (!dname) { return False; } - if (mkdir(dname, 0700)==-1) { + if (mkdir(dname, 0755)==-1) { DEBUG(0,("create_local_private_krb5_conf_for_domain: " "failed to create directory %s. Error was %s\n", dname, strerror(errno) )); @@ -519,7 +519,7 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do while (loopcount < 10) { SMB_STRUCT_STAT st; - xfp = x_fopen(fname, O_CREAT|O_WRONLY, 0600); + xfp = x_fopen(fname, O_CREAT|O_WRONLY, 0644); if (!xfp) { TALLOC_FREE(dname); return False; -- cgit From e05728b6693fb5dcac946e2f278dd09193a680c6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 2 Sep 2006 04:46:27 +0000 Subject: r18000: Get nelem/size args right for x_fwrite. Jeremy. (This used to be commit f1c5409b9fa201c6d726857b02515167b0d7cef1) --- source3/libads/kerberos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 79196f87a7..41c1dc00f5 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -548,7 +548,7 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do break; } - if (x_fwrite(file_contents, flen, 1, xfp) != flen) { + if (x_fwrite(file_contents, 1, flen, xfp) != flen) { unlink(fname); x_fclose(xfp); TALLOC_FREE(dname); -- cgit From d31ee84d888145ca0c89a201befb32def65c5995 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 2 Sep 2006 04:50:08 +0000 Subject: r18001: Proper error reporting on write/close fail. Jeremy. (This used to be commit ba311ac4eac060c12cafeeb8e458f45c2927aabf) --- source3/libads/kerberos.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 41c1dc00f5..fa07602c58 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -478,6 +478,7 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do char *fname = NULL; char *file_contents = NULL; size_t flen = 0; + size_t ret; char *realm_upper = NULL; int loopcount = 0; @@ -548,13 +549,18 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do break; } - if (x_fwrite(file_contents, 1, flen, xfp) != flen) { + ret = x_fwrite(file_contents, 1, flen, xfp); + if (flen != ret) { + DEBUG(0,("create_local_private_krb5_conf_for_domain: x_fwrite failed," + " returned %u. Errno %s\n", (unsigned int)ret, strerror(errno) )); unlink(fname); x_fclose(xfp); TALLOC_FREE(dname); return False; } if (x_fclose(xfp)==-1) { + DEBUG(0,("create_local_private_krb5_conf_for_domain: x_fclose failed." + " Errno %s\n", strerror(errno) )); unlink(fname); TALLOC_FREE(dname); return False; -- cgit From 0a847b4111c6f5979910bba574e8ab1c86deec88 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 2 Sep 2006 04:53:04 +0000 Subject: r18002: Improved debug. Jeremy. (This used to be commit 5f84c8c815ff0c941ef06d682dcc4be52e8867d2) --- source3/libads/kerberos.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index fa07602c58..1d44c28a3c 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -552,7 +552,8 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do ret = x_fwrite(file_contents, 1, flen, xfp); if (flen != ret) { DEBUG(0,("create_local_private_krb5_conf_for_domain: x_fwrite failed," - " returned %u. Errno %s\n", (unsigned int)ret, strerror(errno) )); + " returned %u (should be %u). Errno %s\n", + (unsigned int)ret, (unsigned int)flen, strerror(errno) )); unlink(fname); x_fclose(xfp); TALLOC_FREE(dname); -- cgit From b05c81a184d8763e5f0e25642d7ec4bf80ae8466 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 2 Sep 2006 05:55:47 +0000 Subject: r18003: Creating a directory and getting EEXIST isn't an error. Jeremy. (This used to be commit 515f86167bd9ec64170218f2ea4fb20d12a28365) --- source3/libads/kerberos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 1d44c28a3c..a7c9e3dcba 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -485,7 +485,7 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do if (!dname) { return False; } - if (mkdir(dname, 0755)==-1) { + if ((mkdir(dname, 0755)==-1) && (errno != EEXIST)) { DEBUG(0,("create_local_private_krb5_conf_for_domain: " "failed to create directory %s. Error was %s\n", dname, strerror(errno) )); -- cgit From d0bbe3751a2bc23fc9fa1428423ef2856fb9868e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 2 Sep 2006 06:28:48 +0000 Subject: r18004: If you're writing out a krb5.conf, at least get the syntax right... :-). Jeremy. (This used to be commit ecca467e463ef5c9acd48ee0a5f446755bd2f306) --- source3/libads/kerberos.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index a7c9e3dcba..4801aec23e 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -505,9 +505,9 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do realm_upper = talloc_strdup(fname, realm); strupper_m(realm_upper); - file_contents = talloc_asprintf(fname, "[libdefaults]\n\tdefault_realm = %s\n" + file_contents = talloc_asprintf(fname, "[libdefaults]\n\tdefault_realm = %s\n\n" "[realms]\n\t%s = {\n" - "\t\tkdc = %s\n]\n", + "\t\tkdc = %s\n\t}\n", realm_upper, realm_upper, inet_ntoa(ip)); if (!file_contents) { -- cgit From 0f1bc28744d8c7cae2fe2774b50fc4336408a74d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 2 Sep 2006 19:27:44 +0000 Subject: r18006: Actually a smaller change than it looks. Leverage the get_dc_list code to get the _kerberos. names for site support. This way we don't depend on one KDC to do ticket refresh. Even though we know it's up when we add it, it may go down when we're trying to refresh. Jeremy. (This used to be commit 77fe2a3d7418012a8dbfb6aaeb2a8dd57c6e1a5d) --- source3/libads/dns.c | 45 +++++++++++++++++++++++++++++++++-------- source3/libads/kerberos.c | 51 +++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 86 insertions(+), 10 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/dns.c b/source3/libads/dns.c index 579296ea1f..d5c851d5ca 100644 --- a/source3/libads/dns.c +++ b/source3/libads/dns.c @@ -649,18 +649,20 @@ BOOL stored_sitename_changed(const char *sitename) Query with optional sitename. ********************************************************************/ -NTSTATUS ads_dns_query_dcs_internal(TALLOC_CTX *ctx, - const char *domain, +NTSTATUS ads_dns_query_internal(TALLOC_CTX *ctx, + const char *servicename, + const char *realm, const char *sitename, struct dns_rr_srv **dclist, int *numdcs ) { char *name; if (sitename) { - name = talloc_asprintf(ctx, "_ldap._tcp.%s._sites.dc._msdcs.%s", - sitename, domain ); + name = talloc_asprintf(ctx, "%s._tcp.%s._sites.dc._msdcs.%s", + servicename, sitename, realm ); } else { - name = talloc_asprintf(ctx, "_ldap._tcp.dc._msdcs.%s", domain ); + name = talloc_asprintf(ctx, "%s._tcp.dc._msdcs.%s", + servicename, realm ); } if (!name) { return NT_STATUS_NO_MEMORY; @@ -673,17 +675,44 @@ NTSTATUS ads_dns_query_dcs_internal(TALLOC_CTX *ctx, ********************************************************************/ NTSTATUS ads_dns_query_dcs(TALLOC_CTX *ctx, - const char *domain, + const char *realm, struct dns_rr_srv **dclist, int *numdcs ) { NTSTATUS status; char *sitename = sitename_fetch(); - status = ads_dns_query_dcs_internal(ctx, domain, sitename, dclist, numdcs); + status = ads_dns_query_internal(ctx, "_ldap", realm, sitename, + dclist, numdcs); if (sitename && !NT_STATUS_IS_OK(status)) { /* Sitename DNS query may have failed. Try without. */ - status = ads_dns_query_dcs_internal(ctx, domain, NULL, dclist, numdcs); + status = ads_dns_query_internal(ctx, "_ldap", realm, NULL, + dclist, numdcs); + } + SAFE_FREE(sitename); + return status; +} + +/******************************************************************** + Query for AD KDC's. Transparently use sitename. + Even if our underlying kerberos libraries are UDP only, this + is pretty safe as it's unlikely that a KDC supports TCP and not UDP. +********************************************************************/ + +NTSTATUS ads_dns_query_kdcs(TALLOC_CTX *ctx, + const char *realm, + struct dns_rr_srv **dclist, + int *numdcs ) +{ + NTSTATUS status; + char *sitename = sitename_fetch(); + + status = ads_dns_query_internal(ctx, "_kerberos", realm, sitename, + dclist, numdcs); + if (sitename && !NT_STATUS_IS_OK(status)) { + /* Sitename DNS query may have failed. Try without. */ + status = ads_dns_query_internal(ctx, "_kerberos", realm, NULL, + dclist, numdcs); } SAFE_FREE(sitename); return status; diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 4801aec23e..c872508fe8 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -464,6 +464,46 @@ int kerberos_kinit_password(const char *principal, 0); } +/************************************************************************ + Create a string list of available kdc's, possibly searching by sitename. + Does DNS queries. +************************************************************************/ + +static char *get_kdc_ip_string(char *mem_ctx, const char *realm, struct in_addr primary_ip) +{ + struct ip_service *ip_srv; + int count, i; + char *kdc_str = talloc_asprintf(mem_ctx, "\tkdc = %s\n", + inet_ntoa(primary_ip)); + + if (kdc_str == NULL) { + return NULL; + } + + if (!NT_STATUS_IS_OK(get_kdc_list(realm, &ip_srv, &count))) { + DEBUG(10,("get_kdc_ip_string: get_kdc_list failed. Returning %s\n", + kdc_str )); + return kdc_str; + } + + for (i = 0; i < count; i++) { + if (ip_equal(ip_srv[i].ip, primary_ip)) { + continue; + } + /* Append to the string - inefficient but not done often. */ + kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n", + kdc_str, inet_ntoa(ip_srv[i].ip)); + if (!kdc_str) { + return NULL; + } + } + + DEBUG(10,("get_kdc_ip_string: Returning %s\n", + kdc_str )); + + return kdc_str; +} + /************************************************************************ Create a specific krb5.conf file in the private directory pointing at a specific kdc for a realm. Keyed off domain name. Sets @@ -477,6 +517,7 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do char *dname = talloc_asprintf(NULL, "%s/smb_krb5", lp_lockdir()); char *fname = NULL; char *file_contents = NULL; + char *kdc_ip_string; size_t flen = 0; size_t ret; char *realm_upper = NULL; @@ -505,10 +546,16 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do realm_upper = talloc_strdup(fname, realm); strupper_m(realm_upper); + kdc_ip_string = get_kdc_ip_string(dname, realm, ip); + if (!kdc_ip_string) { + TALLOC_FREE(dname); + return False; + } + file_contents = talloc_asprintf(fname, "[libdefaults]\n\tdefault_realm = %s\n\n" "[realms]\n\t%s = {\n" - "\t\tkdc = %s\n\t}\n", - realm_upper, realm_upper, inet_ntoa(ip)); + "\t\t%s\t}\n", + realm_upper, realm_upper, kdc_ip_string); if (!file_contents) { TALLOC_FREE(dname); -- cgit From fea5d59b8411244b31df7980bdcdab9ed20dc712 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 2 Sep 2006 23:06:21 +0000 Subject: r18010: Ensure we don't timeout twice to the same server in winbindd when it's down and listed in the -ve connection cache. Fix memory leak, reduce timeout for cldap calls - minimum 3 secs. Jeremy. (This used to be commit 10b32cb6de234fa17fdd691bb294864d4d40f782) --- source3/libads/cldap.c | 4 +++- source3/libads/kerberos.c | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/cldap.c b/source3/libads/cldap.c index da1dec6b93..8e34e27353 100644 --- a/source3/libads/cldap.c +++ b/source3/libads/cldap.c @@ -188,6 +188,8 @@ static int recv_cldap_netlogon(int sock, struct cldap_netlogon_reply *reply) DATA_BLOB blob; DATA_BLOB os1, os2, os3; 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); char *p; blob = data_blob(NULL, 8192); @@ -200,7 +202,7 @@ static int recv_cldap_netlogon(int sock, struct cldap_netlogon_reply *reply) /* Setup timeout */ gotalarm = 0; CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig); - alarm(lp_ldap_timeout()); + alarm(al_secs); /* End setup timeout. */ ret = read(sock, blob.data, blob.length); diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index c872508fe8..57233f2182 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -494,10 +494,13 @@ static char *get_kdc_ip_string(char *mem_ctx, const char *realm, struct in_addr kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n", kdc_str, inet_ntoa(ip_srv[i].ip)); if (!kdc_str) { + SAFE_FREE(ip_srv); return NULL; } } + SAFE_FREE(ip_srv); + DEBUG(10,("get_kdc_ip_string: Returning %s\n", kdc_str )); -- cgit From 98cfbd3ccfb3d2255a65289410e5e358ff3d1a64 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 3 Sep 2006 03:46:07 +0000 Subject: r18015: Try and detect network failures immediately in set_dc_type_and_flags(). Fix problem when DC is down in ads_connect, where we fall back to NetBIOS and try exactly the same IP addresses we just put in the negative connection cache.... We can never succeed, so don't try lookups a second time. Jeremy. (This used to be commit 2d28f3e94a1a87bc9e9ed6630ef48b1ce17022e8) --- source3/libads/ldap.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index b23bc277e8..a02f954360 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -286,6 +286,26 @@ again: if ( !NT_STATUS_IS_OK(check_negative_conn_cache(realm, server)) ) continue; + + if (!got_realm) { + /* realm in this case is a workgroup name. We need + to ignore any IP addresses in the negative connection + cache that match ip addresses returned in the ad realm + case. It sucks that I have to reproduce the logic above... */ + c_realm = ads->server.realm; + if ( !c_realm || !*c_realm ) { + if ( !ads->server.workgroup || !*ads->server.workgroup ) { + c_realm = lp_realm(); + } + } + if (c_realm && *c_realm && + !NT_STATUS_IS_OK(check_negative_conn_cache(c_realm, server))) { + /* Ensure we add the workgroup name for this + IP address as negative too. */ + add_failed_connection_entry( realm, server, NT_STATUS_UNSUCCESSFUL ); + continue; + } + } if ( ads_try_connect(ads, server) ) { SAFE_FREE(ip_list); -- cgit From ee0e397d6f003c583768803aa27716b2b7a23981 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 3 Sep 2006 21:07:16 +0000 Subject: r18019: Fix a C++ warnings: Don't use void * in libads/ for LDAPMessage anymore. Compiled it on systems with and without LDAP, I hope it does not break the build farm too badly. If it does, I'll fix it tomorrow. Volker (This used to be commit b2ff9680ebe0979fbeef7f2dabc2e3f27c959d11) --- source3/libads/ldap.c | 180 +++++++++++++++++++++--------------------- source3/libads/ldap_printer.c | 7 +- source3/libads/ldap_schema.c | 6 +- source3/libads/ldap_user.c | 3 +- source3/libads/ldap_utils.c | 41 +++++----- source3/libads/sasl.c | 2 +- 6 files changed, 123 insertions(+), 116 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index a02f954360..970311d5ca 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -438,7 +438,8 @@ static struct berval *dup_berval(TALLOC_CTX *ctx, const struct berval *in_val) if (in_val->bv_len == 0) return value; value->bv_len = in_val->bv_len; - value->bv_val = TALLOC_MEMDUP(ctx, in_val->bv_val, in_val->bv_len); + value->bv_val = (char *)TALLOC_MEMDUP(ctx, in_val->bv_val, + in_val->bv_len); return value; } @@ -517,10 +518,12 @@ static char **ads_pull_strvals(TALLOC_CTX *ctx, const char **in_vals) * @param cookie The paged results cookie to be returned on subsequent calls * @return status of search **/ -ADS_STATUS ads_do_paged_search_args(ADS_STRUCT *ads, const char *bind_path, - int scope, const char *expr, - const char **attrs, void *args, void **res, - int *count, void **cookie) +static ADS_STATUS ads_do_paged_search_args(ADS_STRUCT *ads, + const char *bind_path, + int scope, const char *expr, + const char **attrs, void *args, + LDAPMessage **res, + int *count, struct berval **cookie) { int rc, i, version; char *utf8_expr, *utf8_path, **search_attrs; @@ -693,10 +696,10 @@ done: return ADS_ERROR(rc); } -ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, - int scope, const char *expr, - const char **attrs, void **res, - int *count, void **cookie) +static ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, + int scope, const char *expr, + const char **attrs, LDAPMessage **res, + int *count, struct berval **cookie) { return ads_do_paged_search_args(ads, bind_path, scope, expr, attrs, NULL, res, count, cookie); } @@ -713,11 +716,12 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, * @param res ** which will contain results - free res* with ads_msgfree() * @return status of search **/ -ADS_STATUS ads_do_search_all_args(ADS_STRUCT *ads, const char *bind_path, - int scope, const char *expr, - const char **attrs, void *args, void **res) + ADS_STATUS ads_do_search_all_args(ADS_STRUCT *ads, const char *bind_path, + int scope, const char *expr, + const char **attrs, void *args, + LDAPMessage **res) { - void *cookie = NULL; + struct berval *cookie = NULL; int count = 0; ADS_STATUS status; @@ -730,7 +734,7 @@ ADS_STATUS ads_do_search_all_args(ADS_STRUCT *ads, const char *bind_path, #ifdef HAVE_LDAP_ADD_RESULT_ENTRY while (cookie) { - void *res2 = NULL; + LDAPMessage *res2 = NULL; ADS_STATUS status2; LDAPMessage *msg, *next; @@ -756,9 +760,9 @@ ADS_STATUS ads_do_search_all_args(ADS_STRUCT *ads, const char *bind_path, return status; } -ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, - int scope, const char *expr, - const char **attrs, void **res) + ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, + int scope, const char *expr, + const char **attrs, LDAPMessage **res) { return ads_do_search_all_args(ads, bind_path, scope, expr, attrs, NULL, res); } @@ -780,10 +784,10 @@ ADS_STATUS ads_do_search_all_fn(ADS_STRUCT *ads, const char *bind_path, BOOL(*fn)(char *, void **, void *), void *data_area) { - void *cookie = NULL; + struct berval *cookie = NULL; int count = 0; ADS_STATUS status; - void *res; + LDAPMessage *res; status = ads_do_paged_search(ads, bind_path, scope, expr, attrs, &res, &count, &cookie); @@ -816,9 +820,9 @@ ADS_STATUS ads_do_search_all_fn(ADS_STRUCT *ads, const char *bind_path, * @param res ** which will contain results - free res* with ads_msgfree() * @return status of search **/ -ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, - const char *expr, - const char **attrs, void **res) + ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, + const char *expr, + const char **attrs, LDAPMessage **res) { int rc; char *utf8_expr, *utf8_path, **search_attrs = NULL; @@ -880,9 +884,8 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, * @param attrs Attributes to retrieve * @return status of search **/ -ADS_STATUS ads_search(ADS_STRUCT *ads, void **res, - const char *expr, - const char **attrs) + ADS_STATUS ads_search(ADS_STRUCT *ads, LDAPMessage **res, + const char *expr, const char **attrs) { return ads_do_search(ads, ads->config.bind_path, LDAP_SCOPE_SUBTREE, expr, attrs, res); @@ -896,12 +899,11 @@ ADS_STATUS ads_search(ADS_STRUCT *ads, void **res, * @param attrs Attributes to retrieve * @return status of search **/ -ADS_STATUS ads_search_dn(ADS_STRUCT *ads, void *_res, - const char *dn, - const char **attrs) + ADS_STATUS ads_search_dn(ADS_STRUCT *ads, LDAPMessage **res, + const char *dn, const char **attrs) { - void **res = (void **)_res; - return ads_do_search(ads, dn, LDAP_SCOPE_BASE, "(objectclass=*)", attrs, res); + return ads_do_search(ads, dn, LDAP_SCOPE_BASE, "(objectclass=*)", + attrs, res); } /** @@ -909,7 +911,7 @@ ADS_STATUS ads_search_dn(ADS_STRUCT *ads, void *_res, * @param ads connection to ads server * @param msg Search results to free **/ -void ads_msgfree(ADS_STRUCT *ads, void *msg) + void ads_msgfree(ADS_STRUCT *ads, LDAPMessage *msg) { if (!msg) return; ldap_msgfree(msg); @@ -931,7 +933,7 @@ void ads_memfree(ADS_STRUCT *ads, void *mem) * @param msg Search result * @return dn string **/ -char *ads_get_dn(ADS_STRUCT *ads, void *msg) + char *ads_get_dn(ADS_STRUCT *ads, LDAPMessage *msg) { char *utf8_dn, *unix_dn; @@ -957,7 +959,7 @@ char *ads_get_dn(ADS_STRUCT *ads, void *msg) * @param msg Search result * @return dn string **/ -char *ads_get_dn_canonical(ADS_STRUCT *ads, void *msg) + char *ads_get_dn_canonical(ADS_STRUCT *ads, LDAPMessage *msg) { #ifdef HAVE_LDAP_DN2AD_CANONICAL return ldap_dn2ad_canonical(ads_get_dn(ads, msg)); @@ -995,7 +997,8 @@ char *ads_parent_dn(const char *dn) * @param host Hostname to search for * @return status of search **/ -ADS_STATUS ads_find_machine_acct(ADS_STRUCT *ads, void **res, const char *machine) + ADS_STATUS ads_find_machine_acct(ADS_STRUCT *ads, LDAPMessage **res, + const char *machine) { ADS_STATUS status; char *expr; @@ -1271,7 +1274,7 @@ char *ads_ou_string(ADS_STRUCT *ads, const char *org_unit) char *ads_default_ou_string(ADS_STRUCT *ads, const char *wknguid) { ADS_STATUS status; - void *res; + LDAPMessage *res; char *base, *wkn_dn, *ret, **wkn_dn_exp, **bind_dn_exp; const char *attrs[] = {"distinguishedName", NULL}; int new_ln, wkn_ln, bind_ln, i; @@ -1338,7 +1341,8 @@ char *ads_default_ou_string(ADS_STRUCT *ads, const char *wknguid) ADS_STATUS ads_add_strlist(TALLOC_CTX *ctx, ADS_MODLIST *mods, const char *name, const char **vals) { - return ads_modlist_add(ctx, mods, LDAP_MOD_ADD, name, (const void **) vals); + return ads_modlist_add(ctx, mods, LDAP_MOD_ADD, name, + (const void *) vals); } /** @@ -1361,7 +1365,7 @@ uint32 ads_get_kvno(ADS_STRUCT *ads, const char *machine_name) if (asprintf(&filter, "(samAccountName=%s$)", machine_name) == -1) { return kvno; } - ret = ads_search(ads, (void**)(void *)&res, filter, attrs); + ret = ads_search(ads, &res, filter, attrs); SAFE_FREE(filter); if (!ADS_ERR_OK(ret) && ads_count_replies(ads, res)) { DEBUG(1,("ads_get_kvno: Computer Account For %s not found.\n", machine_name)); @@ -1415,7 +1419,7 @@ ADS_STATUS ads_clear_service_principal_names(ADS_STRUCT *ads, const char *machin ADS_STATUS ret = ADS_ERROR(LDAP_SUCCESS); char *dn_string = NULL; - ret = ads_find_machine_acct(ads, (void **)(void *)&res, machine_name); + ret = ads_find_machine_acct(ads, &res, machine_name); if (!ADS_ERR_OK(ret) || ads_count_replies(ads, res) != 1) { DEBUG(5,("ads_clear_service_principal_names: WARNING: Host Account for %s not found... skipping operation.\n", machine_name)); DEBUG(5,("ads_clear_service_principal_names: WARNING: Service Principals for %s have NOT been cleared.\n", machine_name)); @@ -1484,7 +1488,7 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n char *dn_string = NULL; const char *servicePrincipalName[3] = {NULL, NULL, NULL}; - ret = ads_find_machine_acct(ads, (void **)(void *)&res, machine_name); + ret = ads_find_machine_acct(ads, &res, machine_name); if (!ADS_ERR_OK(ret) || ads_count_replies(ads, res) != 1) { DEBUG(1,("ads_add_service_principal_name: WARNING: Host Account for %s not found... skipping operation.\n", machine_name)); @@ -1751,7 +1755,7 @@ static BOOL ads_dump_field(char *field, void **values, void *data_area) * @param res Results to dump **/ -void ads_dump(ADS_STRUCT *ads, void *res) + void ads_dump(ADS_STRUCT *ads, LDAPMessage *res) { ads_process_results(ads, res, ads_dump_field, NULL); } @@ -1767,11 +1771,11 @@ void ads_dump(ADS_STRUCT *ads, void *res) * @param fn Function for processing each result * @param data_area user-defined area to pass to function **/ -void ads_process_results(ADS_STRUCT *ads, void *res, - BOOL(*fn)(char *, void **, void *), - void *data_area) + void ads_process_results(ADS_STRUCT *ads, LDAPMessage *res, + BOOL(*fn)(char *, void **, void *), + void *data_area) { - void *msg; + LDAPMessage *msg; TALLOC_CTX *ctx; if (!(ctx = talloc_init("ads_process_results"))) @@ -1836,9 +1840,9 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) * @param res Results of search * @return first entry from result **/ -void *ads_first_entry(ADS_STRUCT *ads, void *res) + LDAPMessage *ads_first_entry(ADS_STRUCT *ads, LDAPMessage *res) { - return (void *)ldap_first_entry(ads->ld, (LDAPMessage *)res); + return ldap_first_entry(ads->ld, res); } /** @@ -1847,9 +1851,9 @@ void *ads_first_entry(ADS_STRUCT *ads, void *res) * @param res Results of search * @return next entry from result **/ -void *ads_next_entry(ADS_STRUCT *ads, void *res) + LDAPMessage *ads_next_entry(ADS_STRUCT *ads, LDAPMessage *res) { - return (void *)ldap_next_entry(ads->ld, (LDAPMessage *)res); + return ldap_next_entry(ads->ld, res); } /** @@ -1860,8 +1864,8 @@ void *ads_next_entry(ADS_STRUCT *ads, void *res) * @param field Attribute to retrieve * @return Result string in talloc context **/ -char *ads_pull_string(ADS_STRUCT *ads, - TALLOC_CTX *mem_ctx, void *msg, const char *field) + char *ads_pull_string(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, LDAPMessage *msg, + const char *field) { char **values; char *ret = NULL; @@ -1891,9 +1895,9 @@ char *ads_pull_string(ADS_STRUCT *ads, * @param field Attribute to retrieve * @return Result strings in talloc context **/ -char **ads_pull_strings(ADS_STRUCT *ads, - TALLOC_CTX *mem_ctx, void *msg, const char *field, - size_t *num_values) + char **ads_pull_strings(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, + LDAPMessage *msg, const char *field, + size_t *num_values) { char **values; char **ret = NULL; @@ -1936,13 +1940,13 @@ char **ads_pull_strings(ADS_STRUCT *ads, * @param more_values Are there more values to get? * @return Result strings in talloc context **/ -char **ads_pull_strings_range(ADS_STRUCT *ads, - TALLOC_CTX *mem_ctx, - void *msg, const char *field, - char **current_strings, - const char **next_attribute, - size_t *num_strings, - BOOL *more_strings) + char **ads_pull_strings_range(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + LDAPMessage *msg, const char *field, + char **current_strings, + const char **next_attribute, + size_t *num_strings, + BOOL *more_strings) { char *attr; char *expected_range_attrib, *range_attr; @@ -2059,8 +2063,8 @@ char **ads_pull_strings_range(ADS_STRUCT *ads, * @param v Pointer to int to store result * @return boolean inidicating success */ -BOOL ads_pull_uint32(ADS_STRUCT *ads, - void *msg, const char *field, uint32 *v) + BOOL ads_pull_uint32(ADS_STRUCT *ads, LDAPMessage *msg, const char *field, + uint32 *v) { char **values; @@ -2084,8 +2088,7 @@ BOOL ads_pull_uint32(ADS_STRUCT *ads, * @param guid 37-byte area to receive text guid * @return boolean indicating success **/ -BOOL ads_pull_guid(ADS_STRUCT *ads, - void *msg, struct uuid *guid) + BOOL ads_pull_guid(ADS_STRUCT *ads, LDAPMessage *msg, struct uuid *guid) { char **values; UUID_FLAT flat_guid; @@ -2114,8 +2117,8 @@ BOOL ads_pull_guid(ADS_STRUCT *ads, * @param sid Pointer to sid to store result * @return boolean inidicating success */ -BOOL ads_pull_sid(ADS_STRUCT *ads, - void *msg, const char *field, DOM_SID *sid) + BOOL ads_pull_sid(ADS_STRUCT *ads, LDAPMessage *msg, const char *field, + DOM_SID *sid) { struct berval **values; BOOL ret = False; @@ -2141,8 +2144,8 @@ BOOL ads_pull_sid(ADS_STRUCT *ads, * @param sids pointer to sid array to allocate * @return the count of SIDs pulled **/ -int ads_pull_sids(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, - void *msg, const char *field, DOM_SID **sids) + int ads_pull_sids(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, + LDAPMessage *msg, const char *field, DOM_SID **sids) { struct berval **values; BOOL ret; @@ -2185,8 +2188,8 @@ int ads_pull_sids(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, * @param sd Pointer to *SEC_DESC to store result (talloc()ed) * @return boolean inidicating success */ -BOOL ads_pull_sd(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, - void *msg, const char *field, SEC_DESC **sd) + BOOL ads_pull_sd(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, + LDAPMessage *msg, const char *field, SEC_DESC **sd) { struct berval **values; prs_struct ps; @@ -2218,7 +2221,8 @@ BOOL ads_pull_sd(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, * @param msg Results of search * @return the username */ -char *ads_pull_username(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, void *msg) + char *ads_pull_username(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, + LDAPMessage *msg) { #if 0 /* JERRY */ char *ret, *p; @@ -2248,7 +2252,7 @@ ADS_STATUS ads_USN(ADS_STRUCT *ads, uint32 *usn) { const char *attrs[] = {"highestCommittedUSN", NULL}; ADS_STATUS status; - void *res; + LDAPMessage *res; status = ads_do_search_retry(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); if (!ADS_ERR_OK(status)) @@ -2290,7 +2294,7 @@ ADS_STATUS ads_current_time(ADS_STRUCT *ads) { const char *attrs[] = {"currentTime", NULL}; ADS_STATUS status; - void *res; + LDAPMessage *res; char *timestr; TALLOC_CTX *ctx; ADS_STRUCT *ads_s = ads; @@ -2355,7 +2359,7 @@ ADS_STATUS ads_domain_func_level(ADS_STRUCT *ads, uint32 *val) { const char *attrs[] = {"domainFunctionality", NULL}; ADS_STATUS status; - void *res; + LDAPMessage *res; ADS_STRUCT *ads_s = ads; *val = DS_DOMAIN_FUNCTION_2000; @@ -2411,7 +2415,7 @@ done: ADS_STATUS ads_domain_sid(ADS_STRUCT *ads, DOM_SID *sid) { const char *attrs[] = {"objectSid", NULL}; - void *res; + LDAPMessage *res; ADS_STATUS rc; rc = ads_do_search_retry(ads, ads->config.bind_path, LDAP_SCOPE_BASE, "(objectclass=*)", @@ -2436,7 +2440,7 @@ ADS_STATUS ads_domain_sid(ADS_STRUCT *ads, DOM_SID *sid) ADS_STATUS ads_site_dn(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char **site_name) { ADS_STATUS status; - void *res; + LDAPMessage *res; const char *dn, *service_name; const char *attrs[] = { "dsServiceName", NULL }; @@ -2480,7 +2484,7 @@ ADS_STATUS ads_site_dn(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char **site_n ADS_STATUS ads_site_dn_for_machine(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char *computer_name, const char **site_dn) { ADS_STATUS status; - void *res; + LDAPMessage *res; const char *parent, *config_context, *filter; const char *attrs[] = { "configurationNamingContext", NULL }; char *dn; @@ -2549,7 +2553,7 @@ ADS_STATUS ads_site_dn_for_machine(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const c ADS_STATUS ads_upn_suffixes(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char **suffixes, size_t *num_suffixes) { ADS_STATUS status; - void *res; + LDAPMessage *res; const char *config_context, *base; const char *attrs[] = { "configurationNamingContext", NULL }; const char *attrs2[] = { "uPNSuffixes", NULL }; @@ -2578,7 +2582,7 @@ ADS_STATUS ads_upn_suffixes(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char **suffixe return ADS_ERROR(LDAP_NO_SUCH_OBJECT); } - suffixes = ads_pull_strings(ads, mem_ctx, &res, "uPNSuffixes", num_suffixes); + suffixes = ads_pull_strings(ads, mem_ctx, res, "uPNSuffixes", num_suffixes); if (suffixes == NULL) { ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_MEMORY); @@ -2675,12 +2679,12 @@ BOOL ads_get_sid_from_extended_dn(TALLOC_CTX *mem_ctx, * @param sids pointer to sid array to allocate * @return the count of SIDs pulled **/ -int ads_pull_sids_from_extendeddn(ADS_STRUCT *ads, - TALLOC_CTX *mem_ctx, - void *msg, - const char *field, - enum ads_extended_dn_flags flags, - DOM_SID **sids) + int ads_pull_sids_from_extendeddn(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + LDAPMessage *msg, + const char *field, + enum ads_extended_dn_flags flags, + DOM_SID **sids) { int i; size_t dn_count; @@ -2722,7 +2726,7 @@ char* ads_get_dnshostname( ADS_STRUCT *ads, TALLOC_CTX *ctx, const char *machine int count = 0; char *name = NULL; - status = ads_find_machine_acct(ads, (void **)(void *)&res, global_myname()); + status = ads_find_machine_acct(ads, &res, global_myname()); if (!ADS_ERR_OK(status)) { DEBUG(0,("ads_get_dnshostname: Failed to find account for %s\n", global_myname())); @@ -2754,7 +2758,7 @@ char* ads_get_upn( ADS_STRUCT *ads, TALLOC_CTX *ctx, const char *machine_name ) int count = 0; char *name = NULL; - status = ads_find_machine_acct(ads, (void **)(void *)&res, global_myname()); + status = ads_find_machine_acct(ads, &res, global_myname()); if (!ADS_ERR_OK(status)) { DEBUG(0,("ads_get_upn: Failed to find account for %s\n", global_myname())); @@ -2786,7 +2790,7 @@ char* ads_get_samaccountname( ADS_STRUCT *ads, TALLOC_CTX *ctx, const char *mach int count = 0; char *name = NULL; - status = ads_find_machine_acct(ads, (void **)(void *)&res, global_myname()); + status = ads_find_machine_acct(ads, &res, global_myname()); if (!ADS_ERR_OK(status)) { DEBUG(0,("ads_get_dnshostname: Failed to find account for %s\n", global_myname())); diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index 12bf6eec1d..50233140f0 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -27,8 +27,9 @@ Note that results "res" may be allocated on return so that the results can be used. It should be freed using ads_msgfree. */ -ADS_STATUS ads_find_printer_on_server(ADS_STRUCT *ads, void **res, - const char *printer, const char *servername) + ADS_STATUS ads_find_printer_on_server(ADS_STRUCT *ads, LDAPMessage **res, + const char *printer, + const char *servername) { ADS_STATUS status; char *srv_dn, **srv_cn, *s; @@ -53,7 +54,7 @@ ADS_STATUS ads_find_printer_on_server(ADS_STRUCT *ads, void **res, return status; } -ADS_STATUS ads_find_printers(ADS_STRUCT *ads, void **res) + ADS_STATUS ads_find_printers(ADS_STRUCT *ads, LDAPMessage **res) { const char *ldap_expr; const char *attrs[] = { "objectClass", "printerName", "location", "driverName", diff --git a/source3/libads/ldap_schema.c b/source3/libads/ldap_schema.c index b65ff956ac..30d0cb2c0d 100644 --- a/source3/libads/ldap_schema.c +++ b/source3/libads/ldap_schema.c @@ -29,7 +29,7 @@ ADS_STATUS ads_get_attrnames_by_oids(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char ***OIDs_out, char ***names, size_t *count) { ADS_STATUS status; - void *res = NULL; + LDAPMessage *res = NULL; LDAPMessage *msg; char *expr = NULL; const char *attrs[] = { "lDAPDisplayName", "attributeId", NULL }; @@ -111,7 +111,7 @@ const char *ads_get_attrname_by_oid(ADS_STRUCT *ads, const char *schema_path, TA { ADS_STATUS rc; int count = 0; - void *res = NULL; + LDAPMessage *res = NULL; char *expr = NULL; const char *attrs[] = { "lDAPDisplayName", NULL }; char *result; @@ -155,7 +155,7 @@ failed: static ADS_STATUS ads_schema_path(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char **schema_path) { ADS_STATUS status; - void *res; + LDAPMessage *res; const char *schema; const char *attrs[] = { "schemaNamingContext", NULL }; diff --git a/source3/libads/ldap_user.c b/source3/libads/ldap_user.c index 3ff6acc9e8..66d94d29d3 100644 --- a/source3/libads/ldap_user.c +++ b/source3/libads/ldap_user.c @@ -25,7 +25,8 @@ /* find a user account */ -ADS_STATUS ads_find_user_acct(ADS_STRUCT *ads, void **res, const char *user) + ADS_STATUS ads_find_user_acct(ADS_STRUCT *ads, LDAPMessage **res, + const char *user) { ADS_STATUS status; char *ldap_exp; diff --git a/source3/libads/ldap_utils.c b/source3/libads/ldap_utils.c index c3074233e2..4392cde00b 100644 --- a/source3/libads/ldap_utils.c +++ b/source3/libads/ldap_utils.c @@ -29,7 +29,8 @@ */ static ADS_STATUS ads_do_search_retry_internal(ADS_STRUCT *ads, const char *bind_path, int scope, const char *expr, - const char **attrs, void *args, void **res) + const char **attrs, void *args, + LDAPMessage **res) { ADS_STATUS status = ADS_SUCCESS; int count = 3; @@ -99,41 +100,41 @@ static ADS_STATUS ads_do_search_retry_internal(ADS_STRUCT *ads, const char *bind return status; } -ADS_STATUS ads_do_search_retry(ADS_STRUCT *ads, const char *bind_path, int scope, - const char *expr, - const char **attrs, void **res) + ADS_STATUS ads_do_search_retry(ADS_STRUCT *ads, const char *bind_path, + int scope, const char *expr, + const char **attrs, LDAPMessage **res) { return ads_do_search_retry_internal(ads, bind_path, scope, expr, attrs, NULL, res); } -ADS_STATUS ads_do_search_retry_args(ADS_STRUCT *ads, const char *bind_path, int scope, - const char *expr, - const char **attrs, void *args, void **res) + ADS_STATUS ads_do_search_retry_args(ADS_STRUCT *ads, const char *bind_path, + int scope, const char *expr, + const char **attrs, void *args, + LDAPMessage **res) { return ads_do_search_retry_internal(ads, bind_path, scope, expr, attrs, args, res); } -ADS_STATUS ads_search_retry(ADS_STRUCT *ads, void **res, - const char *expr, - const char **attrs) + ADS_STATUS ads_search_retry(ADS_STRUCT *ads, LDAPMessage **res, + const char *expr, const char **attrs) { return ads_do_search_retry(ads, ads->config.bind_path, LDAP_SCOPE_SUBTREE, expr, attrs, res); } -ADS_STATUS ads_search_retry_dn(ADS_STRUCT *ads, void **res, - const char *dn, - const char **attrs) + ADS_STATUS ads_search_retry_dn(ADS_STRUCT *ads, LDAPMessage **res, + const char *dn, + const char **attrs) { return ads_do_search_retry(ads, dn, LDAP_SCOPE_BASE, "(objectclass=*)", attrs, res); } -ADS_STATUS ads_search_retry_extended_dn(ADS_STRUCT *ads, void **res, - const char *dn, - const char **attrs, - enum ads_extended_dn_flags flags) + ADS_STATUS ads_search_retry_extended_dn(ADS_STRUCT *ads, LDAPMessage **res, + const char *dn, + const char **attrs, + enum ads_extended_dn_flags flags) { ads_control args; @@ -145,9 +146,9 @@ ADS_STATUS ads_search_retry_extended_dn(ADS_STRUCT *ads, void **res, "(objectclass=*)", attrs, &args, res); } -ADS_STATUS ads_search_retry_sid(ADS_STRUCT *ads, void **res, - const DOM_SID *sid, - const char **attrs) + ADS_STATUS ads_search_retry_sid(ADS_STRUCT *ads, LDAPMessage **res, + const DOM_SID *sid, + const char **attrs) { char *dn, *sid_string; ADS_STATUS status; diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index b2613071b7..fe31ef94bb 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -453,7 +453,7 @@ ADS_STATUS ads_sasl_bind(ADS_STRUCT *ads) char **values; ADS_STATUS status; int i, j; - void *res; + LDAPMessage *res; /* get a list of supported SASL mechanisms */ status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); -- cgit From f8a17bd8bdbb52b200671e7ed52ffd982419f3f6 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 4 Sep 2006 19:47:48 +0000 Subject: r18047: More C++ stuff (This used to be commit 86f4ca84f2df2aa8977eb24828e3aa840dda7201) --- source3/libads/kerberos_verify.c | 4 ++-- source3/libads/sasl.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 3aa0860809..dc2f2a1e78 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -101,7 +101,7 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut if (strequal(entry_princ_s, valid_princ_formats[i])) { number_matched_principals++; p_packet->length = ticket->length; - p_packet->data = (krb5_pointer)ticket->data; + p_packet->data = (char *)ticket->data; *pp_tkt = NULL; ret = krb5_rd_req_return_keyblock_from_keytab(context, &auth_context, p_packet, @@ -228,7 +228,7 @@ static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context au /* CIFS doesn't use addresses in tickets. This would break NAT. JRA */ p_packet->length = ticket->length; - p_packet->data = (krb5_pointer)ticket->data; + p_packet->data = (char *)ticket->data; /* We need to setup a auth context with each possible encoding type in turn. */ for (i=0;enctypes[i];i++) { diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index fe31ef94bb..c3f496938a 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -348,7 +348,7 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) goto failed; } - cred.bv_val = output_token.value; + cred.bv_val = (char *)output_token.value; cred.bv_len = output_token.length; rc = ldap_sasl_bind_s(ads->ld, NULL, "GSSAPI", &cred, NULL, NULL, @@ -397,7 +397,7 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) gss_release_buffer(&minor_status, &output_token); output_token.value = SMB_MALLOC(strlen(ads->config.bind_path) + 8); - p = output_token.value; + p = (uint8 *)output_token.value; *p++ = 1; /* no sign & seal selection */ /* choose the same size as the server gave us */ @@ -419,7 +419,7 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) free(output_token.value); - cred.bv_val = input_token.value; + cred.bv_val = (char *)input_token.value; cred.bv_len = input_token.length; rc = ldap_sasl_bind_s(ads->ld, NULL, "GSSAPI", &cred, NULL, NULL, -- cgit From 8d812f8eed301365a550bf36394c0f2774d57188 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 5 Sep 2006 06:32:46 +0000 Subject: r18063: When we get a successful connection using ADS, cache the SAF name under both the domain name and the realm name, as we could be looking up under both. Jerry please check. Jeremy. (This used to be commit 9d954d2deb46698b3834c7caf5ee0cfe628086b5) --- source3/libads/ldap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 970311d5ca..6c3ab75340 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -393,8 +393,9 @@ got_connection: return ADS_ERROR(LDAP_OPERATIONS_ERROR); } - /* cache the successful connection */ + /* cache the successful connection for workgroup and realm */ saf_store( ads->server.workgroup, inet_ntoa(ads->ldap_ip)); + saf_store( ads->server.realm, inet_ntoa(ads->ldap_ip)); ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); -- cgit From 30c0e93156817a469a125f5fe7bb466f3bee4cb7 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 6 Sep 2006 11:53:13 +0000 Subject: r18162: Close socket when the CLDAP request has failed. Guenther (This used to be commit 714ea3ceab714e23e97eb3e4d7261456a18abbac) --- source3/libads/cldap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libads') diff --git a/source3/libads/cldap.c b/source3/libads/cldap.c index 8e34e27353..5f7f1b179f 100644 --- a/source3/libads/cldap.c +++ b/source3/libads/cldap.c @@ -297,6 +297,7 @@ BOOL ads_cldap_netlogon(const char *server, const char *realm, struct cldap_net ret = send_cldap_netlogon(sock, realm, global_myname(), 6); if (ret != 0) { + close(sock); return False; } ret = recv_cldap_netlogon(sock, reply); -- cgit From 73d25f6f784513aa850de4a7207a1436289c107c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 6 Sep 2006 12:14:58 +0000 Subject: r18165: Fix memleaks. Guenther (This used to be commit 6f301b2dc3dd64b4396e1d0307b3d539bda67d45) --- source3/libads/ldap.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 6c3ab75340..0b7ca46e3e 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2260,10 +2260,15 @@ ADS_STATUS ads_USN(ADS_STRUCT *ads, uint32 *usn) return status; if (ads_count_replies(ads, res) != 1) { + ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); } - ads_pull_uint32(ads, res, "highestCommittedUSN", usn); + if (!ads_pull_uint32(ads, res, "highestCommittedUSN", usn)) { + ads_msgfree(ads, res); + return ADS_ERROR(LDAP_NO_SUCH_ATTRIBUTE); + } + ads_msgfree(ads, res); return ADS_SUCCESS; } @@ -2325,7 +2330,7 @@ ADS_STATUS ads_current_time(ADS_STRUCT *ads) timestr = ads_pull_string(ads_s, ctx, res, "currentTime"); if (!timestr) { - ads_msgfree(ads, res); + ads_msgfree(ads_s, res); status = ADS_ERROR(LDAP_NO_RESULTS_RETURNED); goto done; } -- cgit From 5a87bbd48a30a3bff8ab70b44b76fed220b098a9 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 6 Sep 2006 12:34:00 +0000 Subject: r18172: Just a little more verbosity in this debug statement. Guenther (This used to be commit e852bc46464fe6dbdf8530f43fcb88fd2eafae67) --- source3/libads/ldap_utils.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap_utils.c b/source3/libads/ldap_utils.c index 4392cde00b..9559ae117a 100644 --- a/source3/libads/ldap_utils.c +++ b/source3/libads/ldap_utils.c @@ -85,8 +85,8 @@ static ADS_STATUS ads_do_search_retry_internal(ADS_STRUCT *ads, const char *bind *res = NULL; status = ads_do_search_all_args(ads, bp, scope, expr, attrs, args, res); if (ADS_ERR_OK(status)) { - DEBUG(5,("Search for %s gave %d replies\n", - expr, ads_count_replies(ads, *res))); + DEBUG(5,("Search for filter: %s, base: %s gave %d replies\n", + expr, bp, ads_count_replies(ads, *res))); SAFE_FREE(bp); return status; } -- cgit From 4bc83e60de829f57f4587b91d5da51efa49f26f4 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 6 Sep 2006 13:10:20 +0000 Subject: r18174: Do not return "success" when we failed to write in the CLDAP code. Guenther (This used to be commit 1fe4724f57f4f25ed486240cb1e741da60f0c997) --- source3/libads/cldap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libads') diff --git a/source3/libads/cldap.c b/source3/libads/cldap.c index 5f7f1b179f..81901d2fd3 100644 --- a/source3/libads/cldap.c +++ b/source3/libads/cldap.c @@ -160,6 +160,7 @@ static int send_cldap_netlogon(int sock, const char *domain, if (write(sock, data.data, data.length) != (ssize_t)data.length) { DEBUG(2,("failed to send cldap query (%s)\n", strerror(errno))); + return -1; } asn1_free(&data); -- cgit From 171a5cd5c01e120cac6c9dadaccd90e98ad836e4 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 6 Sep 2006 13:13:12 +0000 Subject: r18175: Forgot to call asn1_free() in previous commit. Guenther (This used to be commit af3779a51624977088c322ac98f52c02e9291b54) --- source3/libads/cldap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libads') diff --git a/source3/libads/cldap.c b/source3/libads/cldap.c index 81901d2fd3..72018c620d 100644 --- a/source3/libads/cldap.c +++ b/source3/libads/cldap.c @@ -160,6 +160,7 @@ static int send_cldap_netlogon(int sock, const char *domain, if (write(sock, data.data, data.length) != (ssize_t)data.length) { DEBUG(2,("failed to send cldap query (%s)\n", strerror(errno))); + asn1_free(&data); return -1; } -- cgit From b5f6cbbe1be4379a1ebab1f70ef05af838d48fb7 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 6 Sep 2006 13:20:06 +0000 Subject: r18177: Some build- and memleak-fixes for the (not build by default) ADS GPO routines. Guenther (This used to be commit 0ef504a0a6dc8f5db1dbc7f2410aa981e11fd56c) --- source3/libads/gpo_util.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/gpo_util.c b/source3/libads/gpo_util.c index 8f913c1971..7df38eb125 100644 --- a/source3/libads/gpo_util.c +++ b/source3/libads/gpo_util.c @@ -445,7 +445,7 @@ ADS_STATUS gpo_password_policy(ADS_STRUCT *ads, struct GROUP_POLICY_OBJECT *gpo_list; const char *attrs[] = {"distinguishedName", "userAccountControl", NULL}; char *filter, *dn; - void *res = NULL; + LDAPMessage *res = NULL; uint32 uac; return ADS_ERROR_NT(NT_STATUS_NOT_IMPLEMENTED); @@ -473,15 +473,18 @@ ADS_STATUS gpo_password_policy(ADS_STRUCT *ads, } if (!ads_pull_uint32(ads, res, "userAccountControl", &uac)) { + ads_memfree(ads, dn); return ADS_ERROR(LDAP_NO_MEMORY); } if (!(uac & UF_WORKSTATION_TRUST_ACCOUNT)) { + ads_memfree(ads, dn); return ADS_ERROR(LDAP_NO_SUCH_OBJECT); } status = ads_get_gpo_list(ads, mem_ctx, dn, GPO_LIST_FLAG_MACHINE, &gpo_list); if (!ADS_ERR_OK(status)) { + ads_memfree(ads, dn); return status; } @@ -489,8 +492,10 @@ ADS_STATUS gpo_password_policy(ADS_STRUCT *ads, cse_gpo_name_to_guid_string("Security"), GPO_LIST_FLAG_MACHINE); if (!ADS_ERR_OK(status)) { + ads_memfree(ads, dn); return status; } + ads_memfree(ads, dn); return ADS_ERROR(LDAP_SUCCESS); } -- cgit From 995205fc60f87e1a02aa1c6f309db55ae18e908a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 6 Sep 2006 18:32:20 +0000 Subject: r18188: merge 3.0-libndr branch (This used to be commit 1115745caed3093c25d6be01ffee21819fb0a675) --- source3/libads/authdata.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c index c3c160dafb..71294941a6 100644 --- a/source3/libads/authdata.c +++ b/source3/libads/authdata.c @@ -878,9 +878,9 @@ static void dump_pac_logon_info(PAC_LOGON_INFO *logon_info) { DEBUG(2,("decode_pac_data: Logon time mismatch between ticket and PAC!\n")); DEBUGADD(2, ("decode_pac_data: PAC: %s\n", - http_timestring(nt_time_to_unix(&logon_name->logon_time)))); + http_timestring(nt_time_to_unix(logon_name->logon_time)))); DEBUGADD(2, ("decode_pac_data: Ticket: %s\n", - http_timestring(nt_time_to_unix(&tgs_authtime_nttime)))); + http_timestring(nt_time_to_unix(tgs_authtime_nttime)))); nt_status = NT_STATUS_ACCESS_DENIED; goto out; -- cgit From 6d4c7b13450f2c302a267f42c1b8bf1e8a30b639 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 7 Sep 2006 04:01:11 +0000 Subject: r18200: Experimental code to allow system /etc/krb5.conf to be overwritten by winbindd. Don't enable this :-). Jeremy. (This used to be commit 88e11ee91a2e97c93f5d34313d45b1e38f793038) --- source3/libads/kerberos.c | 105 +++++++++++++++++++++++++++------------------- 1 file changed, 63 insertions(+), 42 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 57233f2182..d2a2c806a9 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -516,15 +516,15 @@ static char *get_kdc_ip_string(char *mem_ctx, const char *realm, struct in_addr BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *domain, struct in_addr ip) { - XFILE *xfp = NULL; char *dname = talloc_asprintf(NULL, "%s/smb_krb5", lp_lockdir()); + char *tmpname = NULL; char *fname = NULL; char *file_contents = NULL; char *kdc_ip_string; size_t flen = 0; - size_t ret; + ssize_t ret; + int fd; char *realm_upper = NULL; - int loopcount = 0; if (!dname) { return False; @@ -537,6 +537,12 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do return False; } + tmpname = talloc_asprintf(dname, "%s/smb_tmp_krb5.XXXXXX", lp_lockdir()); + if (!tmpname) { + TALLOC_FREE(dname); + return False; + } + fname = talloc_asprintf(dname, "%s/krb5.conf.%s", dname, domain); if (!fname) { TALLOC_FREE(dname); @@ -567,52 +573,36 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do flen = strlen(file_contents); - while (loopcount < 10) { - SMB_STRUCT_STAT st; - - xfp = x_fopen(fname, O_CREAT|O_WRONLY, 0644); - if (!xfp) { - TALLOC_FREE(dname); - return False; - } - /* Lock the file. */ - if (!fcntl_lock(xfp->fd, F_SETLKW, 0, 1, F_WRLCK)) { - unlink(fname); - x_fclose(xfp); - TALLOC_FREE(dname); - return False; - } - - /* We got the lock. Is the file still there ? */ - if (sys_stat(fname,&st)==-1) { - if (errno == ENOENT) { - /* Nope - try again up to 10x */ - x_fclose(xfp); - loopcount++; - continue; - } - unlink(fname); - x_fclose(xfp); - TALLOC_FREE(dname); - return False; - } - break; + fd = smb_mkstemp(tmpname); + if (fd == -1) { + DEBUG(0,("create_local_private_krb5_conf_for_domain: smb_mkstemp failed," + " for file %s. Errno %s\n", + tmpname, strerror(errno) )); } - ret = x_fwrite(file_contents, 1, flen, xfp); + ret = write(fd, file_contents, flen); if (flen != ret) { - DEBUG(0,("create_local_private_krb5_conf_for_domain: x_fwrite failed," - " returned %u (should be %u). Errno %s\n", - (unsigned int)ret, (unsigned int)flen, strerror(errno) )); - unlink(fname); - x_fclose(xfp); + DEBUG(0,("create_local_private_krb5_conf_for_domain: write failed," + " returned %d (should be %u). Errno %s\n", + (int)ret, (unsigned int)flen, strerror(errno) )); + unlink(tmpname); + close(fd); TALLOC_FREE(dname); return False; } - if (x_fclose(xfp)==-1) { - DEBUG(0,("create_local_private_krb5_conf_for_domain: x_fclose failed." + if (close(fd)==-1) { + DEBUG(0,("create_local_private_krb5_conf_for_domain: close failed." " Errno %s\n", strerror(errno) )); - unlink(fname); + unlink(tmpname); + TALLOC_FREE(dname); + return False; + } + + if (rename(tmpname, fname) == -1) { + DEBUG(0,("create_local_private_krb5_conf_for_domain: rename " + "of %s to %s failed. Errno %s\n", + tmpname, fname, strerror(errno) )); + unlink(tmpname); TALLOC_FREE(dname); return False; } @@ -623,6 +613,37 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do /* Set the environment variable to this file. */ setenv("KRB5_CONFIG", fname, 1); + +#if defined(OVERWRITE_SYSTEM_KRB5_CONF) + + /* Insanity, sheer insanity..... */ + + if (symlink(fname, "/etc/krb5.conf") == -1) { + if (errno != EEXIST) { + DEBUG(0,("create_local_private_krb5_conf_for_domain: symlink " + "of %s to /etc/krb5.conf failed. Errno %s\n", + fname, strerror(errno) )); + TALLOC_FREE(dname); + return True; /* Not a fatal error. */ + } + + if (unlink("/etc/krb5.conf") == -1) { + DEBUG(0,("create_local_private_krb5_conf_for_domain: unlink " + "of /etc/krb5.conf failed. Errno %s\n", + strerror(errno) )); + TALLOC_FREE(dname); + return True; /* Not a fatal error. */ + } + if (symlink(fname, "/etc/krb5.conf") == -1) { + DEBUG(0,("create_local_private_krb5_conf_for_domain: " + "forced symlink of %s to /etc/krb5.conf failed. Errno %s\n", + fname, strerror(errno) )); + TALLOC_FREE(dname); + return True; /* Not a fatal error. */ + } + } +#endif + TALLOC_FREE(dname); return True; -- cgit From 253c01f29ee8b0287eb47a29683a54ec846d142e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 7 Sep 2006 04:17:23 +0000 Subject: r18201: Make explicit what's going on here. Jeremy. (This used to be commit 38b8a2b5278d2538b9803c2b81f767036a16ad65) --- source3/libads/kerberos.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index d2a2c806a9..40c3019a31 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -520,7 +520,7 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do char *tmpname = NULL; char *fname = NULL; char *file_contents = NULL; - char *kdc_ip_string; + char *kdc_ip_string = NULL; size_t flen = 0; ssize_t ret; int fd; @@ -627,6 +627,7 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do return True; /* Not a fatal error. */ } + /* Yes, this is a race conditon... too bad. */ if (unlink("/etc/krb5.conf") == -1) { DEBUG(0,("create_local_private_krb5_conf_for_domain: unlink " "of /etc/krb5.conf failed. Errno %s\n", -- cgit From 80052bcf13cbac8ac54aacc5dc004a5b5fd4b01e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 7 Sep 2006 17:29:23 +0000 Subject: r18225: If we're going to overwrite krb5.conf, at least be polite enough to make a backup. Jeremy. (This used to be commit c82aac594fd7262029f9c47c2998c9e6b0ffc739) --- source3/libads/kerberos.c | 62 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 42 insertions(+), 20 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 40c3019a31..a0685b8a1c 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -616,31 +616,53 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do #if defined(OVERWRITE_SYSTEM_KRB5_CONF) +#define SYSTEM_KRB5_CONF_PATH "/etc/krb5.conf" /* Insanity, sheer insanity..... */ - if (symlink(fname, "/etc/krb5.conf") == -1) { - if (errno != EEXIST) { - DEBUG(0,("create_local_private_krb5_conf_for_domain: symlink " - "of %s to /etc/krb5.conf failed. Errno %s\n", - fname, strerror(errno) )); - TALLOC_FREE(dname); - return True; /* Not a fatal error. */ - } - /* Yes, this is a race conditon... too bad. */ - if (unlink("/etc/krb5.conf") == -1) { - DEBUG(0,("create_local_private_krb5_conf_for_domain: unlink " - "of /etc/krb5.conf failed. Errno %s\n", - strerror(errno) )); + { + pstring linkpath; + int lret; + + lret = readlink(SYSTEM_KRB5_CONF_PATH, linkpath, sizeof(linkpath)-1); + linkpath[sizeof(pstring)-1] = '\0'; + + if (lret == 0 || strcmp(linkpath, fname) == 0) { + /* Symlink already exists. */ TALLOC_FREE(dname); - return True; /* Not a fatal error. */ + return True; } - if (symlink(fname, "/etc/krb5.conf") == -1) { - DEBUG(0,("create_local_private_krb5_conf_for_domain: " - "forced symlink of %s to /etc/krb5.conf failed. Errno %s\n", - fname, strerror(errno) )); - TALLOC_FREE(dname); - return True; /* Not a fatal error. */ + + /* Try and replace with a symlink. */ + if (symlink(fname, SYSTEM_KRB5_CONF_PATH) == -1) { + if (errno != EEXIST) { + DEBUG(0,("create_local_private_krb5_conf_for_domain: symlink " + "of %s to %s failed. Errno %s\n", + fname, SYSTEM_KRB5_CONF_PATH, strerror(errno) )); + TALLOC_FREE(dname); + return True; /* Not a fatal error. */ + } + + pstrcpy(linkpath, SYSTEM_KRB5_CONF_PATH); + pstrcat(linkpath, ".saved"); + + /* Yes, this is a race conditon... too bad. */ + if (rename(SYSTEM_KRB5_CONF_PATH, linkpath) == -1) { + DEBUG(0,("create_local_private_krb5_conf_for_domain: rename " + "of %s to %s failed. Errno %s\n", + SYSTEM_KRB5_CONF_PATH, linkpath, + strerror(errno) )); + TALLOC_FREE(dname); + return True; /* Not a fatal error. */ + } + + if (symlink(fname, "/etc/krb5.conf") == -1) { + DEBUG(0,("create_local_private_krb5_conf_for_domain: " + "forced symlink of %s to /etc/krb5.conf failed. Errno %s\n", + fname, strerror(errno) )); + TALLOC_FREE(dname); + return True; /* Not a fatal error. */ + } } } #endif -- cgit From 34a25efad28d47db49fe5bd0db08f7988e11bb29 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 7 Sep 2006 18:34:02 +0000 Subject: r18226: Ensure we only do this evil thing if it's our realm. Jeremy. (This used to be commit 0a89b37b1a367470be410ae94b42c813c7dbefe6) --- source3/libads/kerberos.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index a0685b8a1c..7eb0bdc145 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -619,8 +619,7 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do #define SYSTEM_KRB5_CONF_PATH "/etc/krb5.conf" /* Insanity, sheer insanity..... */ - - { + if (strequal(realm, lp_realm())) { pstring linkpath; int lret; -- cgit From ed0274433c438a65468238f1f97c1e809fec7bab Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 7 Sep 2006 21:08:29 +0000 Subject: r18234: DNS failures are too common to log at level zero or 1. Jeremy. (This used to be commit 943e21d5da2a8aadab1b2c3d700a9b8b880582f2) --- source3/libads/dns.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/dns.c b/source3/libads/dns.c index d5c851d5ca..063665d136 100644 --- a/source3/libads/dns.c +++ b/source3/libads/dns.c @@ -287,7 +287,7 @@ static NTSTATUS dns_send_req( TALLOC_CTX *ctx, const char *name, int q_type, } if ( (resp_len = res_query(name, C_IN, q_type, buffer, buf_len)) < 0 ) { - DEBUG(1,("ads_dns_lookup_srv: Failed to resolve %s (%s)\n", name, strerror(errno))); + DEBUG(3,("ads_dns_lookup_srv: Failed to resolve %s (%s)\n", name, strerror(errno))); TALLOC_FREE( buffer ); return NT_STATUS_UNSUCCESSFUL; } @@ -323,7 +323,7 @@ static NTSTATUS ads_dns_lookup_srv( TALLOC_CTX *ctx, const char *name, struct dn status = dns_send_req( ctx, name, T_SRV, &buffer, &resp_len ); if ( !NT_STATUS_IS_OK(status) ) { - DEBUG(0,("ads_dns_lookup_srv: Failed to send DNS query (%s)\n", + DEBUG(3,("ads_dns_lookup_srv: Failed to send DNS query (%s)\n", nt_errstr(status))); return status; } @@ -471,7 +471,7 @@ NTSTATUS ads_dns_lookup_ns( TALLOC_CTX *ctx, const char *dnsdomain, struct dns_r status = dns_send_req( ctx, dnsdomain, T_NS, &buffer, &resp_len ); if ( !NT_STATUS_IS_OK(status) ) { - DEBUG(0,("ads_dns_lookup_ns: Failed to send DNS query (%s)\n", + DEBUG(3,("ads_dns_lookup_ns: Failed to send DNS query (%s)\n", nt_errstr(status))); return status; } -- cgit From 6cfe7be80e7eb2153d7fb503076d84177da7ad4c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 8 Sep 2006 01:16:01 +0000 Subject: r18241: If replacing the krb5.conf, ensure it's readable. Jeremy. (This used to be commit dfd93a30311ff0e57ef23ae1f1cb58d4019a3eee) --- source3/libads/kerberos.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 7eb0bdc145..6374c515ad 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -580,6 +580,16 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do tmpname, strerror(errno) )); } + if (fchmod(fd, 0644)==-1) { + DEBUG(0,("create_local_private_krb5_conf_for_domain: fchmod failed for %s." + " Errno %s\n", + tmpname, strerror(errno) )); + unlink(tmpname); + close(fd); + TALLOC_FREE(dname); + return False; + } + ret = write(fd, file_contents, flen); if (flen != ret) { DEBUG(0,("create_local_private_krb5_conf_for_domain: write failed," -- cgit From 2b27c93a9a8471693d7dcb5fdbe8afe65b22ff66 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 8 Sep 2006 14:28:06 +0000 Subject: r18271: Big change: * autogenerate lsa ndr code * rename 'enum SID_NAME_USE' to 'enum lsa_SidType' * merge a log more security descriptor functions from gen_ndr/ndr_security.c in SAMBA_4_0 The most embarassing thing is the "#define strlen_m strlen" We need a real implementation in SAMBA_3_0 which I'll work on after this code is in. (This used to be commit 3da9f80c28b1e75ef6d46d38fbb81ade6b9fa951) --- source3/libads/ads_utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_utils.c b/source3/libads/ads_utils.c index 0cbf235989..5b450e02dd 100644 --- a/source3/libads/ads_utils.c +++ b/source3/libads/ads_utils.c @@ -135,7 +135,7 @@ uint32 ads_gtype2atype(uint32 gtype) } /* turn a sAMAccountType into a SID_NAME_USE */ -enum SID_NAME_USE ads_atype_map(uint32 atype) +enum lsa_SidType ads_atype_map(uint32 atype) { switch (atype & 0xF0000000) { case ATYPE_GLOBAL_GROUP: -- cgit From 59e5149d8f7972654b17f4eafd8d664fe2bffcde Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 12 Sep 2006 14:45:24 +0000 Subject: r18425: Fix ads_ntstatus(). LDAP_SUCCESS should really map to NT_STATUS_OK. Guenther (This used to be commit 8ab214956ef11ff0b1532713cff65c17d2439570) --- source3/libads/ads_status.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ads_status.c b/source3/libads/ads_status.c index 111a52e072..017d38c600 100644 --- a/source3/libads/ads_status.c +++ b/source3/libads/ads_status.c @@ -76,6 +76,9 @@ NTSTATUS ads_ntstatus(ADS_STATUS status) return map_nt_error_from_unix(status.err.rc); #ifdef HAVE_LDAP case ENUM_ADS_ERROR_LDAP: + if (status.err.rc == LDAP_SUCCESS) { + return NT_STATUS_OK; + } return NT_STATUS_LDAP(status.err.rc); #endif #ifdef HAVE_KRB5 -- cgit From 8c2c5c5d1d3ccbb9f3bab9136c23d1020e4e20f1 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 13 Sep 2006 09:03:42 +0000 Subject: r18446: Add the ldap 'leave domain' code - call this as a non-fatal error path if the 'disable machine account' code succeeded. Jeremy. (This used to be commit f47bffa21ec1caf5ec3a6ec77af801df0b63d83a) --- source3/libads/ldap.c | 174 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 174 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 0b7ca46e3e..93bd9acf4c 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2818,4 +2818,178 @@ out: return name; } +#if 0 + + SAVED CODE - we used to join via ldap - remember how we did this. JRA. + +/** + * Join a machine to a realm + * Creates the machine account and sets the machine password + * @param ads connection to ads server + * @param machine name of host to add + * @param org_unit Organizational unit to place machine in + * @return status of join + **/ +ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *machine_name, + uint32 account_type, const char *org_unit) +{ + ADS_STATUS status; + LDAPMessage *res = NULL; + char *machine; + + /* machine name must be lowercase */ + machine = SMB_STRDUP(machine_name); + strlower_m(machine); + + /* + status = ads_find_machine_acct(ads, (void **)&res, machine); + if (ADS_ERR_OK(status) && ads_count_replies(ads, res) == 1) { + DEBUG(0, ("Host account for %s already exists - deleting old account\n", machine)); + status = ads_leave_realm(ads, machine); + if (!ADS_ERR_OK(status)) { + DEBUG(0, ("Failed to delete host '%s' from the '%s' realm.\n", + machine, ads->config.realm)); + return status; + } + } + */ + status = ads_add_machine_acct(ads, machine, account_type, org_unit); + if (!ADS_ERR_OK(status)) { + DEBUG(0, ("ads_join_realm: ads_add_machine_acct failed (%s): %s\n", machine, ads_errstr(status))); + SAFE_FREE(machine); + return status; + } + + status = ads_find_machine_acct(ads, (void **)(void *)&res, machine); + if (!ADS_ERR_OK(status)) { + DEBUG(0, ("ads_join_realm: Host account test failed for machine %s\n", machine)); + SAFE_FREE(machine); + return status; + } + + SAFE_FREE(machine); + ads_msgfree(ads, res); + + return status; +} +#endif + +/** + * Delete a machine from the realm + * @param ads connection to ads server + * @param hostname Machine to remove + * @return status of delete + **/ +ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) +{ + ADS_STATUS status; + void *msg; + LDAPMessage *res; + char *hostnameDN, *host; + int rc; + LDAPControl ldap_control; + LDAPControl * pldap_control[2] = {NULL, NULL}; + + pldap_control[0] = &ldap_control; + memset(&ldap_control, 0, sizeof(LDAPControl)); + ldap_control.ldctl_oid = (char *)LDAP_SERVER_TREE_DELETE_OID; + + /* hostname must be lowercase */ + host = SMB_STRDUP(hostname); + strlower_m(host); + + status = ads_find_machine_acct(ads, &res, host); + if (!ADS_ERR_OK(status)) { + DEBUG(0, ("Host account for %s does not exist.\n", host)); + SAFE_FREE(host); + return status; + } + + msg = ads_first_entry(ads, res); + if (!msg) { + SAFE_FREE(host); + return ADS_ERROR_SYSTEM(ENOENT); + } + + hostnameDN = ads_get_dn(ads, (LDAPMessage *)msg); + + rc = ldap_delete_ext_s(ads->ld, hostnameDN, pldap_control, NULL); + if (rc) { + DEBUG(3,("ldap_delete_ext_s failed with error code %d\n", rc)); + }else { + DEBUG(3,("ldap_delete_ext_s succeeded with error code %d\n", rc)); + } + + ads_memfree(ads, hostnameDN); + if (rc != LDAP_SUCCESS) { + const char *attrs[] = { "cn", NULL }; + void *msg_sub; + + /* we only search with scope ONE, we do not expect any further + * objects to be created deeper */ + + status = ads_do_search_retry(ads, hostnameDN, LDAP_SCOPE_ONE, + "(objectclass=*)", attrs, &res); + + if (!ADS_ERR_OK(status)) { + SAFE_FREE(host); + ads_memfree(ads, hostnameDN); + return status; + } + + for (msg_sub = ads_first_entry(ads, res); msg_sub; + msg_sub = ads_next_entry(ads, msg_sub)) { + + char *dn = NULL; + + if ((dn = ads_get_dn(ads, msg_sub)) == NULL) { + SAFE_FREE(host); + ads_memfree(ads, hostnameDN); + return ADS_ERROR(LDAP_NO_MEMORY); + } + + status = ads_del_dn(ads, dn); + if (!ADS_ERR_OK(status)) { + DEBUG(3,("failed to delete dn %s: %s\n", dn, ads_errstr(status))); + SAFE_FREE(host); + ads_memfree(ads, dn); + ads_memfree(ads, hostnameDN); + return status; + } + + ads_memfree(ads, dn); + } + + /* there should be no subordinate objects anymore */ + status = ads_do_search_retry(ads, hostnameDN, LDAP_SCOPE_ONE, + "(objectclass=*)", attrs, &res); + + if (!ADS_ERR_OK(status) || ( (ads_count_replies(ads, res)) > 0 ) ) { + SAFE_FREE(host); + ads_memfree(ads, hostnameDN); + return status; + } + + /* delete hostnameDN now */ + status = ads_del_dn(ads, hostnameDN); + if (!ADS_ERR_OK(status)) { + SAFE_FREE(host); + DEBUG(3,("failed to delete dn %s: %s\n", hostnameDN, ads_errstr(status))); + ads_memfree(ads, hostnameDN); + return status; + } + } + + ads_memfree(ads, hostnameDN); + + status = ads_find_machine_acct(ads, &res, host); + if (ADS_ERR_OK(status) && ads_count_replies(ads, res) == 1) { + DEBUG(3, ("Failed to remove host account.\n")); + SAFE_FREE(host); + return status; + } + + SAFE_FREE(host); + return status; +} #endif -- cgit From d3237d2233a96c87417161b6a09035beb2315c1d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 13 Sep 2006 10:03:27 +0000 Subject: r18453: Attempt to fix the non-ldap build (This used to be commit 86db85423027d34cb053fc068159ddd2226e90ec) --- source3/libads/ldap.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 93bd9acf4c..57275dda55 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2874,6 +2874,8 @@ ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *machine_name, } #endif +#ifdef HAVE_LDAP + /** * Delete a machine from the realm * @param ads connection to ads server @@ -2993,3 +2995,5 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) return status; } #endif + +#endif -- cgit From dfa62cfa989f29138818fd4badf213fb35e8b48e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 13 Sep 2006 11:40:21 +0000 Subject: r18464: Solaris has LDAP_SCOPE_ONELEVEL. Linux seems to have it as well. Fix a C++ compat warning. Volker (This used to be commit 351e583f66714562eca1f40429bfee70f06d281c) --- source3/libads/ldap.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 57275dda55..7ea605df60 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2925,13 +2925,14 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) ads_memfree(ads, hostnameDN); if (rc != LDAP_SUCCESS) { const char *attrs[] = { "cn", NULL }; - void *msg_sub; + LDAPMessage *msg_sub; /* we only search with scope ONE, we do not expect any further * objects to be created deeper */ - status = ads_do_search_retry(ads, hostnameDN, LDAP_SCOPE_ONE, - "(objectclass=*)", attrs, &res); + status = ads_do_search_retry(ads, hostnameDN, + LDAP_SCOPE_ONELEVEL, + "(objectclass=*)", attrs, &res); if (!ADS_ERR_OK(status)) { SAFE_FREE(host); @@ -2963,8 +2964,9 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) } /* there should be no subordinate objects anymore */ - status = ads_do_search_retry(ads, hostnameDN, LDAP_SCOPE_ONE, - "(objectclass=*)", attrs, &res); + status = ads_do_search_retry(ads, hostnameDN, + LDAP_SCOPE_ONELEVEL, + "(objectclass=*)", attrs, &res); if (!ADS_ERR_OK(status) || ( (ads_count_replies(ads, res)) > 0 ) ) { SAFE_FREE(host); -- cgit From 6b3c42b1a17956f69ea4a0c345a6b6fcd1429a81 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 13 Sep 2006 13:02:51 +0000 Subject: r18466: Attempt to fix the AIX build (This used to be commit 1398425067d77d90ecf2ed4c17a12d643f7f5a88) --- source3/libads/dns.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/dns.c b/source3/libads/dns.c index 063665d136..c8b3f29507 100644 --- a/source3/libads/dns.c +++ b/source3/libads/dns.c @@ -46,7 +46,9 @@ # define T_A ns_t_a #endif # define T_SRV ns_t_srv +#if !defined(T_NS) /* AIX 5.3 already defines T_NS */ # define T_NS ns_t_ns +#endif #else # ifdef HFIXEDSZ # define NS_HFIXEDSZ HFIXEDSZ -- cgit From a4743f3a76dc88f765f9bc5dde8054b60d3045cc Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 13 Sep 2006 16:21:48 +0000 Subject: r18480: Doh ! Double-free of hostnameDN. Jeremy. (This used to be commit f8984fa8b706bb76559e447b30a201e1cc2871b6) --- source3/libads/ldap.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 7ea605df60..6b18bbf594 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2922,7 +2922,6 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) DEBUG(3,("ldap_delete_ext_s succeeded with error code %d\n", rc)); } - ads_memfree(ads, hostnameDN); if (rc != LDAP_SUCCESS) { const char *attrs[] = { "cn", NULL }; LDAPMessage *msg_sub; -- cgit From dda94fdf96e9a2ec77e98ed6304ffb94252e4c7c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 14 Sep 2006 09:44:48 +0000 Subject: r18508: A query for the LDAP schema can never be done anonymously against AD. Guenther (This used to be commit 8bb6e82f02044a715dbeee020bcc4a01a83c4a64) --- source3/libads/ldap_schema.c | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap_schema.c b/source3/libads/ldap_schema.c index 30d0cb2c0d..da8b168c21 100644 --- a/source3/libads/ldap_schema.c +++ b/source3/libads/ldap_schema.c @@ -181,7 +181,7 @@ static ADS_STATUS ads_schema_path(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char **s * Check for "Services for Unix" or rfc2307 Schema and load some attributes into the ADS_STRUCT * @param ads connection to ads server * @param enum mapping type - * @return BOOL status of search (False if one or more attributes couldn't be + * @return ADS_STATUS status of search (False if one or more attributes couldn't be * found in Active Directory) **/ ADS_STATUS ads_check_posix_schema_mapping(ADS_STRUCT *ads, enum wb_posix_mapping map_type) @@ -191,7 +191,6 @@ ADS_STATUS ads_check_posix_schema_mapping(ADS_STRUCT *ads, enum wb_posix_mapping char **oids_out, **names_out; size_t num_names; char *schema_path = NULL; - ADS_STRUCT *ads_s = ads; int i; const char *oids_sfu[] = { ADS_ATTR_SFU_UIDNUMBER_OID, @@ -236,22 +235,6 @@ ADS_STATUS ads_check_posix_schema_mapping(ADS_STRUCT *ads, enum wb_posix_mapping return ADS_ERROR(LDAP_NO_MEMORY); } - /* establish a new ldap tcp session if necessary */ - - if (!ads->ld) { - if ((ads_s = ads_init(ads->server.realm, ads->server.workgroup, - ads->server.ldap_server)) == NULL) { - status = ADS_ERROR(LDAP_SERVER_DOWN); - goto done; - } - - ads_s->auth.flags = ADS_AUTH_ANON_BIND; - status = ads_connect(ads_s); - if (!ADS_ERR_OK(status)) { - goto done; - } - } - status = ads_schema_path(ads, ctx, &schema_path); if (!ADS_ERR_OK(status)) { DEBUG(3,("ads_check_posix_mapping: Unable to retrieve schema DN!\n")); @@ -321,10 +304,6 @@ ADS_STATUS ads_check_posix_schema_mapping(ADS_STRUCT *ads, enum wb_posix_mapping ads->schema.map_type = map_type; done: - /* free any temporary ads connections */ - if (ads_s != ads) { - ads_destroy(&ads_s); - } if (ctx) { talloc_destroy(ctx); } -- cgit From 2ad8c705b238e8ebb87fed51b962b4e165c1202f Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 14 Sep 2006 10:21:46 +0000 Subject: r18512: Add krb5conf file environment to debug statement. Guenther (This used to be commit 398f368c8a2df36d522583c733f7c22cac2f2059) --- source3/libads/kerberos.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 6374c515ad..76866a8093 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -86,8 +86,9 @@ int kerberos_kinit_password_ext(const char *principal, krb5_set_real_time(ctx, time(NULL) + time_offset, 0); } - DEBUG(10,("kerberos_kinit_password: using %s as ccache\n", - cache_name ? cache_name: krb5_cc_default_name(ctx))); + DEBUG(10,("kerberos_kinit_password: using [%s] as ccache and config [%s]\n", + cache_name ? cache_name: krb5_cc_default_name(ctx), + getenv("KRB5_CONFIG"))); if ((code = krb5_cc_resolve(ctx, cache_name ? cache_name : krb5_cc_default_name(ctx), &cc))) { krb5_free_context(ctx); -- cgit From a0aaa82f6d360f2fe688f95791640b58231ed873 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 15 Sep 2006 14:18:52 +0000 Subject: r18552: Ensure the sitename matches before we SAF store a DC in ADS mode. Jeremy. (This used to be commit 03e1078b459531af5a2336b584b3c886c5dd1e29) --- source3/libads/ldap.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 6b18bbf594..7b31586f7d 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -115,7 +115,6 @@ static int ldap_search_with_timeout(LDAP *ld, return result; } -#ifdef HAVE_KRB5 /********************************************** Do client and server sitename match ? **********************************************/ @@ -139,7 +138,6 @@ BOOL ads_sitename_match(ADS_STRUCT *ads) ads->config.client_site_name ? ads->config.client_site_name : "NULL")); return False; } -#endif /* try a connection to a given ldap server, returning True and setting the servers IP @@ -394,8 +392,10 @@ got_connection: } /* cache the successful connection for workgroup and realm */ - saf_store( ads->server.workgroup, inet_ntoa(ads->ldap_ip)); - saf_store( ads->server.realm, inet_ntoa(ads->ldap_ip)); + if (ads_sitename_match(ads)) { + saf_store( ads->server.workgroup, inet_ntoa(ads->ldap_ip)); + saf_store( ads->server.realm, inet_ntoa(ads->ldap_ip)); + } ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); -- cgit From 245aa33f0d0ccbc55c3ed86ea4417b7358aedccb Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 18 Sep 2006 19:26:09 +0000 Subject: r18620: Fallback to non-paging LDAP searches in ads_do_search_retry_internal() for anonymous bound connections. When doing anonymous bind you can never use paged LDAP control for RootDSE searches on AD. Guenther (This used to be commit dc1d92faabd4b291f607eb481349ba37e52ef11e) --- source3/libads/ldap_utils.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap_utils.c b/source3/libads/ldap_utils.c index 9559ae117a..e6855674d1 100644 --- a/source3/libads/ldap_utils.c +++ b/source3/libads/ldap_utils.c @@ -50,7 +50,15 @@ static ADS_STATUS ads_do_search_retry_internal(ADS_STRUCT *ads, const char *bind } *res = NULL; - status = ads_do_search_all_args(ads, bp, scope, expr, attrs, args, res); + + /* when binding anonymously, we cannot use the paged search LDAP + * control - Guenther */ + + if (ads->auth.flags & ADS_AUTH_ANON_BIND) { + status = ads_do_search(ads, bp, scope, expr, attrs, res); + } else { + status = ads_do_search_all_args(ads, bp, scope, expr, attrs, args, res); + } if (ADS_ERR_OK(status)) { DEBUG(5,("Search for %s gave %d replies\n", expr, ads_count_replies(ads, *res))); @@ -83,7 +91,16 @@ static ADS_STATUS ads_do_search_retry_internal(ADS_STRUCT *ads, const char *bind } *res = NULL; - status = ads_do_search_all_args(ads, bp, scope, expr, attrs, args, res); + + /* when binding anonymously, we cannot use the paged search LDAP + * control - Guenther */ + + if (ads->auth.flags & ADS_AUTH_ANON_BIND) { + status = ads_do_search(ads, bp, scope, expr, attrs, res); + } else { + status = ads_do_search_all_args(ads, bp, scope, expr, attrs, args, res); + } + if (ADS_ERR_OK(status)) { DEBUG(5,("Search for filter: %s, base: %s gave %d replies\n", expr, bp, ads_count_replies(ads, *res))); -- cgit From 664c3f41660847c110ba81759f71a70c88807a76 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 19 Sep 2006 01:07:40 +0000 Subject: r18663: Fix one more uuid -> GUID. Jeremy. (This used to be commit e568271af2b5c20cff70b72b8ab4b1b704122b40) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 7b31586f7d..f9bdb9c651 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2089,7 +2089,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) * @param guid 37-byte area to receive text guid * @return boolean indicating success **/ - BOOL ads_pull_guid(ADS_STRUCT *ads, LDAPMessage *msg, struct uuid *guid) + BOOL ads_pull_guid(ADS_STRUCT *ads, LDAPMessage *msg, struct GUID *guid) { char **values; UUID_FLAT flat_guid; -- cgit From 4fa5a1c8453379e1b1bd39dea14b7e736b9ae41f Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 19 Sep 2006 02:04:11 +0000 Subject: r18670: Fix memleaks. Guenther (This used to be commit 2fc63fb8f7927ea61c565801b4c6308d3a4afcd1) --- source3/libads/ldap_schema.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap_schema.c b/source3/libads/ldap_schema.c index da8b168c21..b4a512cbfe 100644 --- a/source3/libads/ldap_schema.c +++ b/source3/libads/ldap_schema.c @@ -165,10 +165,12 @@ static ADS_STATUS ads_schema_path(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char **s } if ( (schema = ads_pull_string(ads, mem_ctx, res, "schemaNamingContext")) == NULL ) { + ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); } if ( (*schema_path = talloc_strdup(mem_ctx, schema)) == NULL ) { + ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_MEMORY); } -- cgit From 4db7642caa99c1b054322a8971c4b673556487ce Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 20 Sep 2006 22:23:12 +0000 Subject: r18745: Use the Samba4 data structures for security descriptors and security descriptor buffers. Make security access masks simply a uint32 rather than a structure with a uint32 in it. (This used to be commit b41c52b9db5fc4a553b20a7a5a051a4afced9366) --- source3/libads/disp_sec.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/disp_sec.c b/source3/libads/disp_sec.c index c9de447e69..a768ba08f3 100644 --- a/source3/libads/disp_sec.c +++ b/source3/libads/disp_sec.c @@ -90,14 +90,14 @@ static void ads_disp_ace(SEC_ACE *sec_ace) sec_ace->type, sec_ace->flags, sec_ace->size, - sec_ace->info.mask); + sec_ace->access_mask); } else { printf("------- ACE (type: 0x%02x, flags: 0x%02x, size: 0x%02x, mask: 0x%x, object flags: 0x%x)\n", sec_ace->type, sec_ace->flags, sec_ace->size, - sec_ace->info.mask, - sec_ace->obj_flags); + sec_ace->access_mask, + sec_ace->object.object.flags); } if (sec_ace->type == SEC_ACE_TYPE_ACCESS_ALLOWED) { @@ -117,7 +117,7 @@ static void ads_disp_ace(SEC_ACE *sec_ace) printf("access SID: %s\naccess type: %s\n", sid_string_static(&sec_ace->trustee), access_type); - ads_disp_perms(sec_ace->info.mask); + ads_disp_perms(sec_ace->access_mask); } /* display ACL */ @@ -143,15 +143,15 @@ void ads_disp_sd(SEC_DESC *sd) sd->revision, sd->type); printf("owner SID: %s\n", sid_string_static(sd->owner_sid)); - printf("group SID: %s\n", sid_string_static(sd->grp_sid)); + printf("group SID: %s\n", sid_string_static(sd->group_sid)); ads_disp_acl(sd->sacl, "system"); for (i = 0; i < sd->sacl->num_aces; i ++) - ads_disp_ace(&sd->sacl->ace[i]); + ads_disp_ace(&sd->sacl->aces[i]); ads_disp_acl(sd->dacl, "user"); for (i = 0; i < sd->dacl->num_aces; i ++) - ads_disp_ace(&sd->dacl->ace[i]); + ads_disp_ace(&sd->dacl->aces[i]); printf("-------------- End Of Security Descriptor\n"); } -- cgit From 314d563b12cecb357d3ad472291bd33fa78a9b63 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 22 Sep 2006 09:00:59 +0000 Subject: r18816: Fix some build warnings. Guenther (This used to be commit b70ed9e48394ddeaf0102e017cf706ff083e065b) --- source3/libads/gpo.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/gpo.c b/source3/libads/gpo.c index 9cf7aae977..9c3a133516 100644 --- a/source3/libads/gpo.c +++ b/source3/libads/gpo.c @@ -211,7 +211,7 @@ ADS_STATUS ads_get_gpo_link(ADS_STRUCT *ads, { ADS_STATUS status; const char *attrs[] = {"gPLink", "gPOptions", NULL}; - void *res = NULL; + LDAPMessage *res = NULL; const char *gp_link; uint32 gp_options; @@ -254,7 +254,7 @@ ADS_STATUS ads_add_gpo_link(ADS_STRUCT *ads, { ADS_STATUS status; const char *attrs[] = {"gPLink", NULL}; - void *res = NULL; + LDAPMessage *res = NULL; const char *gp_link, *gp_link_new; ADS_MODLIST mods; @@ -309,7 +309,7 @@ ADS_STATUS ads_delete_gpo_link(ADS_STRUCT *ads, { ADS_STATUS status; const char *attrs[] = {"gPLink", NULL}; - void *res = NULL; + LDAPMessage *res = NULL; const char *gp_link, *gp_link_new = NULL; ADS_MODLIST mods; @@ -432,7 +432,7 @@ ADS_STATUS ads_get_gpo(ADS_STRUCT *ads, struct GROUP_POLICY_OBJECT *gpo) { ADS_STATUS status; - void *res = NULL; + LDAPMessage *res = NULL; char *dn; const char *filter; const char *attrs[] = { "cn", "displayName", "flags", "gPCFileSysPath", -- cgit From 0d12a35e6b4434f8aef4431f96cf67857ada31c0 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 22 Sep 2006 09:07:31 +0000 Subject: r18817: Enable the build of the gpo tool but do not make it available yet. Guenther (This used to be commit 927cda5d31e9cb02105df3cfc06f5cb273233747) --- source3/libads/gpo_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/gpo_util.c b/source3/libads/gpo_util.c index 7df38eb125..cabe9a32db 100644 --- a/source3/libads/gpo_util.c +++ b/source3/libads/gpo_util.c @@ -23,7 +23,7 @@ #define DEFAULT_DOMAIN_POLICY "Default Domain Policy" #define DEFAULT_DOMAIN_CONTROLLERS_POLICY "Default Domain Controllers Policy" -/* should we store a parsed guid ? UUID_FLAT guid; */ +/* should we store a parsed guid ? */ struct gpo_table { const char *name; const char *guid_string; -- cgit From a6bb76765aa9759ab8869968bacbd3c5104a9db8 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 22 Sep 2006 09:34:25 +0000 Subject: r18819: Fix build without LDAP. Guenther (This used to be commit a0aedee1c90af163210dd459603dd5dffb73e132) --- source3/libads/gpo.c | 4 ++++ source3/libads/gpo_util.c | 4 ++++ 2 files changed, 8 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/gpo.c b/source3/libads/gpo.c index 9c3a133516..85809d341f 100644 --- a/source3/libads/gpo.c +++ b/source3/libads/gpo.c @@ -20,6 +20,8 @@ #include "includes.h" +#ifdef HAVE_LDAP + ADS_STATUS ads_parse_gp_ext(TALLOC_CTX *mem_ctx, const char *extension_raw, struct GP_EXT *gp_ext) @@ -678,3 +680,5 @@ ADS_STATUS ads_get_gpo_list(ADS_STRUCT *ads, return ADS_ERROR(LDAP_SUCCESS); } + +#endif /* HAVE_LDAP */ diff --git a/source3/libads/gpo_util.c b/source3/libads/gpo_util.c index cabe9a32db..aed99d694f 100644 --- a/source3/libads/gpo_util.c +++ b/source3/libads/gpo_util.c @@ -20,6 +20,8 @@ #include "includes.h" +#ifdef HAVE_LDAP + #define DEFAULT_DOMAIN_POLICY "Default Domain Policy" #define DEFAULT_DOMAIN_CONTROLLERS_POLICY "Default Domain Controllers Policy" @@ -499,3 +501,5 @@ ADS_STATUS gpo_password_policy(ADS_STRUCT *ads, ads_memfree(ads, dn); return ADS_ERROR(LDAP_SUCCESS); } + +#endif /* HAVE_LDAP */ -- cgit From 7fdd258c396ede023e8e5e8067779dc9dfe94ec1 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 22 Sep 2006 10:09:15 +0000 Subject: r18820: Comment out some unused functions. Guenther (This used to be commit cdc81927dbbc542500211ad8e6815815d7764731) --- source3/libads/gpo_util.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/gpo_util.c b/source3/libads/gpo_util.c index aed99d694f..714dcacb8b 100644 --- a/source3/libads/gpo_util.c +++ b/source3/libads/gpo_util.c @@ -37,6 +37,7 @@ struct snapin_table { ADS_STATUS (*snapin_fn)(ADS_STRUCT *, TALLOC_CTX *mem_ctx, const char *, const char *); }; +#if 0 /* unused */ static struct gpo_table gpo_default_policy[] = { { DEFAULT_DOMAIN_POLICY, "31B2F340-016D-11D2-945F-00C04FB984F9" }, @@ -44,7 +45,7 @@ static struct gpo_table gpo_default_policy[] = { "6AC1786C-016F-11D2-945F-00C04fB984F9" }, { NULL, NULL } }; - +#endif /* the following is seen in gPCMachineExtensionNames or gPCUserExtensionNames */ @@ -127,6 +128,19 @@ static const char *guid_string_to_name(const char *guid_string, struct gpo_table return NULL; } +static const char *snapin_guid_string_to_name(const char *guid_string, + struct snapin_table *table) +{ + int i; + for (i = 0; table[i].guid_string; i++) { + if (strequal(guid_string, table[i].guid_string)) { + return table[i].name; + } + } + return NULL; +} + +#if 0 /* unused */ static const char *default_gpo_name_to_guid_string(const char *name) { return name_to_guid_string(name, gpo_default_policy); @@ -136,6 +150,7 @@ static const char *default_gpo_guid_string_to_name(const char *guid) { return guid_string_to_name(guid, gpo_default_policy); } +#endif const char *cse_gpo_guid_string_to_name(const char *guid) { @@ -149,7 +164,7 @@ static const char *cse_gpo_name_to_guid_string(const char *name) const char *cse_snapin_gpo_guid_string_to_name(const char *guid) { - return guid_string_to_name(guid, gpo_cse_snapin_extensions); + return snapin_guid_string_to_name(guid, gpo_cse_snapin_extensions); } void dump_gp_ext(struct GP_EXT *gp_ext) -- cgit From 846aa881cdc5a527d6ec35e085672580a3b59c99 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sat, 23 Sep 2006 21:06:33 +0000 Subject: r18853: Fix remaining warnings. Volker, should be fine now. Guenther (This used to be commit 40a6169aceb51dc7f73ae72ebac2e55c6b1edc3f) --- source3/libads/gpo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/gpo.c b/source3/libads/gpo.c index 85809d341f..1d5cdfa026 100644 --- a/source3/libads/gpo.c +++ b/source3/libads/gpo.c @@ -364,7 +364,7 @@ ADS_STATUS ads_delete_gpo_link(ADS_STRUCT *ads, ADS_STATUS ads_parse_gpo(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, - void *res, + LDAPMessage *res, const char *gpo_dn, struct GROUP_POLICY_OBJECT *gpo) { -- cgit From 78f2900a1691ab03820cfa0b7876518d7c101945 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 24 Sep 2006 03:15:58 +0000 Subject: r18869: two build fixes for systems without ldap the first is to not enable the ldap ldb backend just yet. This will need configure tests to conditionally include. We should be able to use the m4 files from lib/ldb/ The 2nd is to fix libads/gpo.o not to publicly prototype a function that needs ldap.h (This used to be commit 1cf17edc14ebd379b982b589a66e86316ef7087b) --- source3/libads/gpo.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/gpo.c b/source3/libads/gpo.c index 1d5cdfa026..84898ab387 100644 --- a/source3/libads/gpo.c +++ b/source3/libads/gpo.c @@ -362,11 +362,11 @@ ADS_STATUS ads_delete_gpo_link(ADS_STRUCT *ads, return ads_gen_mod(ads, link_dn, mods); } -ADS_STATUS ads_parse_gpo(ADS_STRUCT *ads, - TALLOC_CTX *mem_ctx, - LDAPMessage *res, - const char *gpo_dn, - struct GROUP_POLICY_OBJECT *gpo) + ADS_STATUS ads_parse_gpo(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + LDAPMessage *res, + const char *gpo_dn, + struct GROUP_POLICY_OBJECT *gpo) { ZERO_STRUCTP(gpo); -- cgit From 82bf0da9d33d84023338498a6fde9f9f91b173d8 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sun, 24 Sep 2006 23:44:00 +0000 Subject: r18879: Fix crash for "net ads gpo list". Guenther (This used to be commit 7df5808d8b1d9458dbd47b92750c0b128325335c) --- source3/libads/gpo.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/gpo.c b/source3/libads/gpo.c index 84898ab387..fc7f9064e8 100644 --- a/source3/libads/gpo.c +++ b/source3/libads/gpo.c @@ -380,12 +380,10 @@ ADS_STATUS ads_delete_gpo_link(ADS_STRUCT *ads, gpo->ds_path = ads_get_dn(ads, res); } if (gpo->ds_path == NULL) { - ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_MEMORY); } if (!ads_pull_uint32(ads, res, "versionNumber", &gpo->version)) { - ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_MEMORY); } @@ -395,25 +393,21 @@ ADS_STATUS ads_delete_gpo_link(ADS_STRUCT *ads, /* sure ??? */ if (!ads_pull_uint32(ads, res, "flags", &gpo->options)) { - ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_MEMORY); } gpo->file_sys_path = ads_pull_string(ads, mem_ctx, res, "gPCFileSysPath"); if (gpo->file_sys_path == NULL) { - ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_MEMORY); } gpo->display_name = ads_pull_string(ads, mem_ctx, res, "displayName"); if (gpo->display_name == NULL) { - ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_MEMORY); } gpo->name = ads_pull_string(ads, mem_ctx, res, "name"); if (gpo->name == NULL) { - ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_MEMORY); } @@ -421,8 +415,6 @@ ADS_STATUS ads_delete_gpo_link(ADS_STRUCT *ads, gpo->machine_extensions = ads_pull_string(ads, mem_ctx, res, "gPCMachineExtensionNames"); gpo->user_extensions = ads_pull_string(ads, mem_ctx, res, "gPCUserExtensionNames"); - ads_msgfree(ads, res); - return ADS_ERROR(LDAP_SUCCESS); } @@ -478,16 +470,18 @@ ADS_STATUS ads_get_gpo(ADS_STRUCT *ads, if (ads_count_replies(ads, res) != 1) { DEBUG(10,("ads_get_gpo: no result\n")); + ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_SUCH_OBJECT); } dn = ads_get_dn(ads, res); if (dn == NULL) { + ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_MEMORY); } status = ads_parse_gpo(ads, mem_ctx, res, dn, gpo); - + ads_msgfree(ads, res); ads_memfree(ads, dn); return status; -- cgit From dd992469ddaa849e9a3ec9ae115f574210711c2b Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 25 Sep 2006 16:55:19 +0000 Subject: r18902: Also dump mS-DS-CreatorSID. Guenther (This used to be commit e7cae9bbae2848ca1088a822883563062dd3f612) --- source3/libads/ldap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index f9bdb9c651..89c34f03a9 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1724,6 +1724,7 @@ static BOOL ads_dump_field(char *field, void **values, void *data_area) {"tokenGroups", False, dump_sid}, {"tokenGroupsNoGCAcceptable", False, dump_sid}, {"tokengroupsGlobalandUniversal", False, dump_sid}, + {"mS-DS-CreatorSID", False, dump_sid}, {NULL, True, NULL} }; int i; -- cgit From f7633eca1824f7a5bda733e6753d5d1f850f78c3 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 26 Sep 2006 16:27:18 +0000 Subject: r18923: Fix more memleaks. Guenther (This used to be commit ecb632a1534d5178602b9143bb17712559fe2e4f) --- source3/libads/gpo.c | 6 +++++- source3/libads/gpo_util.c | 11 +++++++---- source3/libads/ldap.c | 13 +++++++++++-- 3 files changed, 23 insertions(+), 7 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/gpo.c b/source3/libads/gpo.c index fc7f9064e8..15ff54854c 100644 --- a/source3/libads/gpo.c +++ b/source3/libads/gpo.c @@ -276,6 +276,7 @@ ADS_STATUS ads_add_gpo_link(ADS_STRUCT *ads, if (ads_count_replies(ads, res) != 1) { DEBUG(10,("ads_add_gpo_link: no result\n")); + ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_SUCH_OBJECT); } @@ -286,6 +287,7 @@ ADS_STATUS ads_add_gpo_link(ADS_STRUCT *ads, gp_link_new = talloc_asprintf(mem_ctx, "%s[%s;%d]", gp_link, gpo_dn, gpo_opt); } + ads_msgfree(ads, res); if (gp_link_new == NULL) { return ADS_ERROR(LDAP_NO_MEMORY); } @@ -334,6 +336,7 @@ ADS_STATUS ads_delete_gpo_link(ADS_STRUCT *ads, if (ads_count_replies(ads, res) != 1) { DEBUG(10,("ads_delete_gpo_link: no result\n")); + ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_SUCH_OBJECT); } @@ -343,8 +346,9 @@ ADS_STATUS ads_delete_gpo_link(ADS_STRUCT *ads, } /* find link to delete */ -// gp_link_new = talloc_asprintf(mem_ctx, "%s[%s;%d]", gp_link, gpo_dn, gpo_opt); + /* gp_link_new = talloc_asprintf(mem_ctx, "%s[%s;%d]", gp_link, gpo_dn, gpo_opt); */ + ads_msgfree(ads, res); if (gp_link_new == NULL) { return ADS_ERROR(LDAP_NO_MEMORY); } diff --git a/source3/libads/gpo_util.c b/source3/libads/gpo_util.c index 714dcacb8b..a30df6e9eb 100644 --- a/source3/libads/gpo_util.c +++ b/source3/libads/gpo_util.c @@ -465,8 +465,6 @@ ADS_STATUS gpo_password_policy(ADS_STRUCT *ads, LDAPMessage *res = NULL; uint32 uac; - return ADS_ERROR_NT(NT_STATUS_NOT_IMPLEMENTED); - filter = talloc_asprintf(mem_ctx, "(&(objectclass=user)(sAMAccountName=%s))", hostname); if (filter == NULL) { return ADS_ERROR(LDAP_NO_MEMORY); @@ -481,19 +479,24 @@ ADS_STATUS gpo_password_policy(ADS_STRUCT *ads, } if (ads_count_replies(ads, res) != 1) { + ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_SUCH_OBJECT); } dn = ads_get_dn(ads, res); if (dn == NULL) { + ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_MEMORY); } if (!ads_pull_uint32(ads, res, "userAccountControl", &uac)) { + ads_msgfree(ads, res); ads_memfree(ads, dn); return ADS_ERROR(LDAP_NO_MEMORY); } + ads_msgfree(ads, res); + if (!(uac & UF_WORKSTATION_TRUST_ACCOUNT)) { ads_memfree(ads, dn); return ADS_ERROR(LDAP_NO_SUCH_OBJECT); @@ -505,15 +508,15 @@ ADS_STATUS gpo_password_policy(ADS_STRUCT *ads, return status; } + ads_memfree(ads, dn); + status = gpo_process_gpo_list(ads, mem_ctx, &gpo_list, cse_gpo_name_to_guid_string("Security"), GPO_LIST_FLAG_MACHINE); if (!ADS_ERR_OK(status)) { - ads_memfree(ads, dn); return status; } - ads_memfree(ads, dn); return ADS_ERROR(LDAP_SUCCESS); } diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 89c34f03a9..6077231ae2 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2458,9 +2458,12 @@ ADS_STATUS ads_site_dn(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char **site_n service_name = ads_pull_string(ads, mem_ctx, res, "dsServiceName"); if (service_name == NULL) { + ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); } + ads_msgfree(ads, res); + /* go up three levels */ dn = ads_parent_dn(ads_parent_dn(ads_parent_dn(service_name))); if (dn == NULL) { @@ -2472,8 +2475,6 @@ ADS_STATUS ads_site_dn(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char **site_n return ADS_ERROR(LDAP_NO_MEMORY); } - ads_msgfree(ads, res); - return status; /* dsServiceName: CN=NTDS Settings,CN=W2K3DC,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=ber,DC=suse,DC=de @@ -2508,37 +2509,45 @@ ADS_STATUS ads_site_dn_for_machine(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const c config_context = ads_pull_string(ads, mem_ctx, res, "configurationNamingContext"); if (config_context == NULL) { + ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_MEMORY); } filter = talloc_asprintf(mem_ctx, "(cn=%s)", computer_name); if (filter == NULL) { + ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_MEMORY); } + ads_msgfree(ads, res); + status = ads_do_search(ads, config_context, LDAP_SCOPE_SUBTREE, filter, NULL, &res); if (!ADS_ERR_OK(status)) { return status; } if (ads_count_replies(ads, res) != 1) { + ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_SUCH_OBJECT); } dn = ads_get_dn(ads, res); if (dn == NULL) { + ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_MEMORY); } /* go up three levels */ parent = ads_parent_dn(ads_parent_dn(ads_parent_dn(dn))); if (parent == NULL) { + ads_msgfree(ads, res); ads_memfree(ads, dn); return ADS_ERROR(LDAP_NO_MEMORY); } *site_dn = talloc_strdup(mem_ctx, parent); if (*site_dn == NULL) { + ads_msgfree(ads, res); ads_memfree(ads, dn); ADS_ERROR(LDAP_NO_MEMORY); } -- cgit From 296b450f16dd45e01d4c495ca085c16e1894adc6 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 27 Sep 2006 04:37:34 +0000 Subject: r18941: Minor cleanup in ads_parse_gpo(). Guenther (This used to be commit 7579a91f81a43f570987fecca03c19f559887685) --- source3/libads/gpo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/gpo.c b/source3/libads/gpo.c index 15ff54854c..4a121e9f6a 100644 --- a/source3/libads/gpo.c +++ b/source3/libads/gpo.c @@ -392,8 +392,8 @@ ADS_STATUS ads_delete_gpo_link(ADS_STRUCT *ads, } /* split here for convenience */ - gpo->version_user = gpo->version >> 16; - gpo->version_machine = gpo->version & 0xffff; + gpo->version_user = GPO_VERSION_USER(gpo->version); + gpo->version_machine = GPO_VERSION_MACHINE(gpo->version); /* sure ??? */ if (!ads_pull_uint32(ads, res, "flags", &gpo->options)) { -- cgit From 73f4ac012aaebfe4f778f6971ce59049c242be7b Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 28 Sep 2006 21:33:54 +0000 Subject: r18982: Move the gpo related functions to "libgpo". Guenther (This used to be commit 1308a842716bc3bd1a9853b9b206dc7308a8c1dd) --- source3/libads/gpo.c | 682 ---------------------------------------------- source3/libads/gpo_util.c | 523 ----------------------------------- 2 files changed, 1205 deletions(-) delete mode 100644 source3/libads/gpo.c delete mode 100644 source3/libads/gpo_util.c (limited to 'source3/libads') diff --git a/source3/libads/gpo.c b/source3/libads/gpo.c deleted file mode 100644 index 4a121e9f6a..0000000000 --- a/source3/libads/gpo.c +++ /dev/null @@ -1,682 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * Group Policy Object Support - * Copyright (C) Guenther Deschner 2005 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include "includes.h" - -#ifdef HAVE_LDAP - -ADS_STATUS ads_parse_gp_ext(TALLOC_CTX *mem_ctx, - const char *extension_raw, - struct GP_EXT *gp_ext) -{ - char **ext_list; - char **ext_strings; - int i; - - DEBUG(20,("ads_parse_gp_ext: %s\n", extension_raw)); - - ext_list = str_list_make_talloc(mem_ctx, extension_raw, "]"); - if (ext_list == NULL) { - goto parse_error; - } - - for (i = 0; ext_list[i] != NULL; i++) { - /* no op */ - } - - gp_ext->num_exts = i; - - gp_ext->extensions = TALLOC_ZERO_ARRAY(mem_ctx, char *, gp_ext->num_exts); - gp_ext->extensions_guid = TALLOC_ZERO_ARRAY(mem_ctx, char *, gp_ext->num_exts); - gp_ext->snapins = TALLOC_ZERO_ARRAY(mem_ctx, char *, gp_ext->num_exts); - gp_ext->snapins_guid = TALLOC_ZERO_ARRAY(mem_ctx, char *, gp_ext->num_exts); - - gp_ext->gp_extension = talloc_strdup(mem_ctx, extension_raw); - - if (gp_ext->extensions == NULL || gp_ext->extensions_guid == NULL || - gp_ext->snapins == NULL || gp_ext->snapins_guid == NULL || - gp_ext->gp_extension == NULL) { - goto parse_error; - } - - for (i = 0; ext_list[i] != NULL; i++) { - - int k; - char *p, *q; - - DEBUGADD(10,("extension #%d\n", i)); - - p = ext_list[i]; - - if (p[0] == '[') { - p++; - } - - ext_strings = str_list_make_talloc(mem_ctx, p, "}"); - if (ext_strings == NULL) { - goto parse_error; - } - - for (k = 0; ext_strings[k] != NULL; k++) { - /* no op */ - } - - q = ext_strings[0]; - - if (q[0] == '{') { - q++; - } - - gp_ext->extensions[i] = talloc_strdup(mem_ctx, cse_gpo_guid_string_to_name(q)); - gp_ext->extensions_guid[i] = talloc_strdup(mem_ctx, q); - - /* we might have no name for the guid */ - if (gp_ext->extensions_guid[i] == NULL) { - goto parse_error; - } - - for (k = 1; ext_strings[k] != NULL; k++) { - - char *m = ext_strings[k]; - - if (m[0] == '{') { - m++; - } - - /* FIXME: theoretically there could be more than one snapin per extension */ - gp_ext->snapins[i] = talloc_strdup(mem_ctx, cse_snapin_gpo_guid_string_to_name(m)); - gp_ext->snapins_guid[i] = talloc_strdup(mem_ctx, m); - - /* we might have no name for the guid */ - if (gp_ext->snapins_guid[i] == NULL) { - goto parse_error; - } - } - } - - if (ext_list) { - str_list_free_talloc(mem_ctx, &ext_list); - } - if (ext_strings) { - str_list_free_talloc(mem_ctx, &ext_strings); - } - - return ADS_ERROR(LDAP_SUCCESS); - -parse_error: - if (ext_list) { - str_list_free_talloc(mem_ctx, &ext_list); - } - if (ext_strings) { - str_list_free_talloc(mem_ctx, &ext_strings); - } - - return ADS_ERROR(LDAP_NO_MEMORY); -} - -ADS_STATUS ads_parse_gplink(TALLOC_CTX *mem_ctx, - const char *gp_link_raw, - uint32 options, - struct GP_LINK *gp_link) -{ - char **link_list; - int i; - - DEBUG(10,("ads_parse_gplink: gPLink: %s\n", gp_link_raw)); - - link_list = str_list_make_talloc(mem_ctx, gp_link_raw, "]"); - if (link_list == NULL) { - goto parse_error; - } - - for (i = 0; link_list[i] != NULL; i++) { - /* no op */ - } - - gp_link->gp_opts = options; - gp_link->num_links = i; - - gp_link->link_names = TALLOC_ZERO_ARRAY(mem_ctx, char *, gp_link->num_links); - gp_link->link_opts = TALLOC_ZERO_ARRAY(mem_ctx, uint32, gp_link->num_links); - - gp_link->gp_link = talloc_strdup(mem_ctx, gp_link_raw); - - if (gp_link->link_names == NULL || gp_link->link_opts == NULL || gp_link->gp_link == NULL) { - goto parse_error; - } - - for (i = 0; link_list[i] != NULL; i++) { - - char *p, *q; - - DEBUGADD(10,("ads_parse_gplink: processing link #%d\n", i)); - - q = link_list[i]; - if (q[0] == '[') { - q++; - }; - - p = strchr(q, ';'); - - if (p == NULL) { - goto parse_error; - } - - gp_link->link_names[i] = talloc_strdup(mem_ctx, q); - if (gp_link->link_names[i] == NULL) { - goto parse_error; - } - gp_link->link_names[i][PTR_DIFF(p, q)] = 0; - - gp_link->link_opts[i] = atoi(p + 1); - - DEBUGADD(10,("ads_parse_gplink: link: %s\n", gp_link->link_names[i])); - DEBUGADD(10,("ads_parse_gplink: opt: %d\n", gp_link->link_opts[i])); - - } - - if (link_list) { - str_list_free_talloc(mem_ctx, &link_list); - } - - return ADS_ERROR(LDAP_SUCCESS); - -parse_error: - if (link_list) { - str_list_free_talloc(mem_ctx, &link_list); - } - - return ADS_ERROR(LDAP_NO_MEMORY); -} - -ADS_STATUS ads_get_gpo_link(ADS_STRUCT *ads, - TALLOC_CTX *mem_ctx, - const char *link_dn, - struct GP_LINK *gp_link_struct) -{ - ADS_STATUS status; - const char *attrs[] = {"gPLink", "gPOptions", NULL}; - LDAPMessage *res = NULL; - const char *gp_link; - uint32 gp_options; - - ZERO_STRUCTP(gp_link_struct); - - status = ads_search_dn(ads, &res, link_dn, attrs); - if (!ADS_ERR_OK(status)) { - DEBUG(10,("ads_get_gpo_link: search failed with %s\n", ads_errstr(status))); - return status; - } - - if (ads_count_replies(ads, res) != 1) { - DEBUG(10,("ads_get_gpo_link: no result\n")); - ads_msgfree(ads, res); - return ADS_ERROR(LDAP_NO_SUCH_OBJECT); - } - - gp_link = ads_pull_string(ads, mem_ctx, res, "gPLink"); - if (gp_link == NULL) { - DEBUG(10,("ads_get_gpo_link: no 'gPLink' attribute found\n")); - ads_msgfree(ads, res); - return ADS_ERROR(LDAP_NO_SUCH_ATTRIBUTE); - } - - if (!ads_pull_uint32(ads, res, "gPOptions", &gp_options)) { - DEBUG(10,("ads_get_gpo_link: no 'gPOptions' attribute found\n")); - gp_options = 0; - } - - ads_msgfree(ads, res); - - return ads_parse_gplink(mem_ctx, gp_link, gp_options, gp_link_struct); -} - -ADS_STATUS ads_add_gpo_link(ADS_STRUCT *ads, - TALLOC_CTX *mem_ctx, - const char *link_dn, - const char *gpo_dn, - uint32 gpo_opt) -{ - ADS_STATUS status; - const char *attrs[] = {"gPLink", NULL}; - LDAPMessage *res = NULL; - const char *gp_link, *gp_link_new; - ADS_MODLIST mods; - - - /* although ADS allows to set anything here, we better check here if - * the gpo_dn is sane */ - - if (!strnequal(gpo_dn, "LDAP://CN={", strlen("LDAP://CN={")) != 0) { - return ADS_ERROR(LDAP_INVALID_DN_SYNTAX); - } - - status = ads_search_dn(ads, &res, link_dn, attrs); - if (!ADS_ERR_OK(status)) { - DEBUG(10,("ads_add_gpo_link: search failed with %s\n", ads_errstr(status))); - return status; - } - - if (ads_count_replies(ads, res) != 1) { - DEBUG(10,("ads_add_gpo_link: no result\n")); - ads_msgfree(ads, res); - return ADS_ERROR(LDAP_NO_SUCH_OBJECT); - } - - gp_link = ads_pull_string(ads, mem_ctx, res, "gPLink"); - if (gp_link == NULL) { - gp_link_new = talloc_asprintf(mem_ctx, "[%s;%d]", gpo_dn, gpo_opt); - } else { - gp_link_new = talloc_asprintf(mem_ctx, "%s[%s;%d]", gp_link, gpo_dn, gpo_opt); - } - - ads_msgfree(ads, res); - if (gp_link_new == NULL) { - return ADS_ERROR(LDAP_NO_MEMORY); - } - - mods = ads_init_mods(mem_ctx); - if (mods == NULL) { - return ADS_ERROR(LDAP_NO_MEMORY); - } - - status = ads_mod_str(mem_ctx, &mods, "gPLink", gp_link_new); - if (!ADS_ERR_OK(status)) { - return status; - } - - return ads_gen_mod(ads, link_dn, mods); -} - -/* untested & broken */ -ADS_STATUS ads_delete_gpo_link(ADS_STRUCT *ads, - TALLOC_CTX *mem_ctx, - const char *link_dn, - const char *gpo_dn) -{ - ADS_STATUS status; - const char *attrs[] = {"gPLink", NULL}; - LDAPMessage *res = NULL; - const char *gp_link, *gp_link_new = NULL; - ADS_MODLIST mods; - - /* check for a sane gpo_dn */ - if (gpo_dn[0] != '[') { - DEBUG(10,("ads_delete_gpo_link: first char not: [\n")); - return ADS_ERROR(LDAP_INVALID_DN_SYNTAX); - } - - if (gpo_dn[strlen(gpo_dn)] != ']') { - DEBUG(10,("ads_delete_gpo_link: last char not: ]\n")); - return ADS_ERROR(LDAP_INVALID_DN_SYNTAX); - } - - status = ads_search_dn(ads, &res, link_dn, attrs); - if (!ADS_ERR_OK(status)) { - DEBUG(10,("ads_delete_gpo_link: search failed with %s\n", ads_errstr(status))); - return status; - } - - if (ads_count_replies(ads, res) != 1) { - DEBUG(10,("ads_delete_gpo_link: no result\n")); - ads_msgfree(ads, res); - return ADS_ERROR(LDAP_NO_SUCH_OBJECT); - } - - gp_link = ads_pull_string(ads, mem_ctx, res, "gPLink"); - if (gp_link == NULL) { - return ADS_ERROR(LDAP_NO_SUCH_ATTRIBUTE); - } - - /* find link to delete */ - /* gp_link_new = talloc_asprintf(mem_ctx, "%s[%s;%d]", gp_link, gpo_dn, gpo_opt); */ - - ads_msgfree(ads, res); - if (gp_link_new == NULL) { - return ADS_ERROR(LDAP_NO_MEMORY); - } - - mods = ads_init_mods(mem_ctx); - if (mods == NULL) { - return ADS_ERROR(LDAP_NO_MEMORY); - } - - status = ads_mod_str(mem_ctx, &mods, "gPLink", gp_link_new); - if (!ADS_ERR_OK(status)) { - return status; - } - - return ads_gen_mod(ads, link_dn, mods); -} - - ADS_STATUS ads_parse_gpo(ADS_STRUCT *ads, - TALLOC_CTX *mem_ctx, - LDAPMessage *res, - const char *gpo_dn, - struct GROUP_POLICY_OBJECT *gpo) -{ - ZERO_STRUCTP(gpo); - - if (res == NULL) { - return ADS_ERROR(LDAP_NO_MEMORY); - } - - if (gpo_dn) { - gpo->ds_path = talloc_strdup(mem_ctx, gpo_dn); - } else { - gpo->ds_path = ads_get_dn(ads, res); - } - if (gpo->ds_path == NULL) { - return ADS_ERROR(LDAP_NO_MEMORY); - } - - if (!ads_pull_uint32(ads, res, "versionNumber", &gpo->version)) { - return ADS_ERROR(LDAP_NO_MEMORY); - } - - /* split here for convenience */ - gpo->version_user = GPO_VERSION_USER(gpo->version); - gpo->version_machine = GPO_VERSION_MACHINE(gpo->version); - - /* sure ??? */ - if (!ads_pull_uint32(ads, res, "flags", &gpo->options)) { - return ADS_ERROR(LDAP_NO_MEMORY); - } - - gpo->file_sys_path = ads_pull_string(ads, mem_ctx, res, "gPCFileSysPath"); - if (gpo->file_sys_path == NULL) { - return ADS_ERROR(LDAP_NO_MEMORY); - } - - gpo->display_name = ads_pull_string(ads, mem_ctx, res, "displayName"); - if (gpo->display_name == NULL) { - return ADS_ERROR(LDAP_NO_MEMORY); - } - - gpo->name = ads_pull_string(ads, mem_ctx, res, "name"); - if (gpo->name == NULL) { - return ADS_ERROR(LDAP_NO_MEMORY); - } - - /* ???, this is optional to have and what does it depend on, the 'flags' ?) */ - gpo->machine_extensions = ads_pull_string(ads, mem_ctx, res, "gPCMachineExtensionNames"); - gpo->user_extensions = ads_pull_string(ads, mem_ctx, res, "gPCUserExtensionNames"); - - return ADS_ERROR(LDAP_SUCCESS); -} - -ADS_STATUS ads_get_gpo(ADS_STRUCT *ads, - TALLOC_CTX *mem_ctx, - const char *gpo_dn, - const char *display_name, - const char *guid_name, - struct GROUP_POLICY_OBJECT *gpo) -{ - ADS_STATUS status; - LDAPMessage *res = NULL; - char *dn; - const char *filter; - const char *attrs[] = { "cn", "displayName", "flags", "gPCFileSysPath", - "gPCFunctionalityVersion", "gPCMachineExtensionNames", - "gPCUserExtensionNames", "gPCWQLFilter", "name", - "versionNumber", NULL}; - - ZERO_STRUCTP(gpo); - - if (!gpo_dn && !display_name && !guid_name) { - return ADS_ERROR(LDAP_NO_SUCH_OBJECT); - } - - if (gpo_dn) { - - if (strnequal(gpo_dn, "LDAP://", strlen("LDAP://")) != 0) { - gpo_dn = gpo_dn + strlen("LDAP://"); - } - - status = ads_search_dn(ads, &res, gpo_dn, attrs); - - } else if (display_name || guid_name) { - - filter = talloc_asprintf(mem_ctx, - "(&(objectclass=groupPolicyContainer)(%s=%s))", - display_name ? "displayName" : "name", - display_name ? display_name : guid_name); - if (filter == NULL) { - return ADS_ERROR(LDAP_NO_MEMORY); - } - - status = ads_do_search_all(ads, ads->config.bind_path, - LDAP_SCOPE_SUBTREE, filter, - attrs, &res); - } - - if (!ADS_ERR_OK(status)) { - DEBUG(10,("ads_get_gpo: search failed with %s\n", ads_errstr(status))); - return status; - } - - if (ads_count_replies(ads, res) != 1) { - DEBUG(10,("ads_get_gpo: no result\n")); - ads_msgfree(ads, res); - return ADS_ERROR(LDAP_NO_SUCH_OBJECT); - } - - dn = ads_get_dn(ads, res); - if (dn == NULL) { - ads_msgfree(ads, res); - return ADS_ERROR(LDAP_NO_MEMORY); - } - - status = ads_parse_gpo(ads, mem_ctx, res, dn, gpo); - ads_msgfree(ads, res); - ads_memfree(ads, dn); - - return status; -} - -ADS_STATUS add_gplink_to_gpo_list(ADS_STRUCT *ads, - TALLOC_CTX *mem_ctx, - struct GROUP_POLICY_OBJECT **gpo_list, - const char *link_dn, - struct GP_LINK *gp_link, - enum GPO_LINK_TYPE link_type, - BOOL only_add_forced_gpos) -{ - ADS_STATUS status; - int i; - - for (i = 0; i < gp_link->num_links; i++) { - - struct GROUP_POLICY_OBJECT *new_gpo = NULL; - - if (gp_link->link_opts[i] & GPO_LINK_OPT_DISABLED) { - DEBUG(10,("skipping disabled GPO\n")); - continue; - } - - if (only_add_forced_gpos) { - - if (! (gp_link->link_opts[i] & GPO_LINK_OPT_ENFORCED)) { - DEBUG(10,("skipping nonenforced GPO link because GPOPTIONS_BLOCK_INHERITANCE has been set\n")); - continue; - } else { - DEBUG(10,("adding enforced GPO link although the GPOPTIONS_BLOCK_INHERITANCE has been set\n")); - } - } - - new_gpo = TALLOC_P(mem_ctx, struct GROUP_POLICY_OBJECT); - if (new_gpo == NULL) { - return ADS_ERROR(LDAP_NO_MEMORY); - } - - ZERO_STRUCTP(new_gpo); - - status = ads_get_gpo(ads, mem_ctx, gp_link->link_names[i], NULL, NULL, new_gpo); - if (!ADS_ERR_OK(status)) { - return status; - } - - new_gpo->link = link_dn; - new_gpo->link_type = link_type; - - DLIST_ADD(*gpo_list, new_gpo); - - DEBUG(10,("add_gplink_to_gplist: added GPLINK #%d %s to GPO list\n", - i, gp_link->link_names[i])); - } - - return ADS_ERROR(LDAP_SUCCESS); -} - -ADS_STATUS ads_get_gpo_list(ADS_STRUCT *ads, - TALLOC_CTX *mem_ctx, - const char *dn, - uint32 flags, - struct GROUP_POLICY_OBJECT **gpo_list) -{ - /* (L)ocal (S)ite (D)omain (O)rganizational(U)nit */ - - ADS_STATUS status; - struct GP_LINK gp_link; - const char *parent_dn, *site_dn, *tmp_dn; - BOOL add_only_forced_gpos = False; - - ZERO_STRUCTP(gpo_list); - - DEBUG(10,("ads_get_gpo_list: getting GPO list for [%s]\n", dn)); - - /* (L)ocal */ - /* not yet... */ - - /* (S)ite */ - - /* are site GPOs valid for users as well ??? */ - if (flags & GPO_LIST_FLAG_MACHINE) { - - status = ads_site_dn_for_machine(ads, mem_ctx, ads->config.ldap_server_name, &site_dn); - if (!ADS_ERR_OK(status)) { - return status; - } - - DEBUG(10,("ads_get_gpo_list: query SITE: [%s] for GPOs\n", site_dn)); - - status = ads_get_gpo_link(ads, mem_ctx, site_dn, &gp_link); - if (ADS_ERR_OK(status)) { - - if (DEBUGLEVEL >= 100) { - dump_gplink(ads, mem_ctx, &gp_link); - } - - status = add_gplink_to_gpo_list(ads, mem_ctx, gpo_list, - site_dn, &gp_link, GP_LINK_SITE, - add_only_forced_gpos); - if (!ADS_ERR_OK(status)) { - return status; - } - - if (flags & GPO_LIST_FLAG_SITEONLY) { - return ADS_ERROR(LDAP_SUCCESS); - } - - /* inheritance can't be blocked at the site level */ - } - } - - tmp_dn = dn; - - while ( (parent_dn = ads_parent_dn(tmp_dn)) && - (!strequal(parent_dn, ads_parent_dn(ads->config.bind_path))) ) { - - /* (D)omain */ - - /* An account can just be a member of one domain */ - if (strncmp(parent_dn, "DC=", strlen("DC=")) == 0) { - - DEBUG(10,("ads_get_gpo_list: query DC: [%s] for GPOs\n", parent_dn)); - - status = ads_get_gpo_link(ads, mem_ctx, parent_dn, &gp_link); - if (ADS_ERR_OK(status)) { - - if (DEBUGLEVEL >= 100) { - dump_gplink(ads, mem_ctx, &gp_link); - } - - /* block inheritance from now on */ - if (gp_link.gp_opts & GPOPTIONS_BLOCK_INHERITANCE) { - add_only_forced_gpos = True; - } - - status = add_gplink_to_gpo_list(ads, mem_ctx, - gpo_list, parent_dn, - &gp_link, GP_LINK_DOMAIN, - add_only_forced_gpos); - if (!ADS_ERR_OK(status)) { - return status; - } - } - } - - tmp_dn = parent_dn; - } - - /* reset dn again */ - tmp_dn = dn; - - while ( (parent_dn = ads_parent_dn(tmp_dn)) && - (!strequal(parent_dn, ads_parent_dn(ads->config.bind_path))) ) { - - - /* (O)rganizational(U)nit */ - - /* An account can be a member of more OUs */ - if (strncmp(parent_dn, "OU=", strlen("OU=")) == 0) { - - DEBUG(10,("ads_get_gpo_list: query OU: [%s] for GPOs\n", parent_dn)); - - status = ads_get_gpo_link(ads, mem_ctx, parent_dn, &gp_link); - if (ADS_ERR_OK(status)) { - - if (DEBUGLEVEL >= 100) { - dump_gplink(ads, mem_ctx, &gp_link); - } - - /* block inheritance from now on */ - if (gp_link.gp_opts & GPOPTIONS_BLOCK_INHERITANCE) { - add_only_forced_gpos = True; - } - - status = add_gplink_to_gpo_list(ads, mem_ctx, - gpo_list, parent_dn, - &gp_link, GP_LINK_OU, - add_only_forced_gpos); - if (!ADS_ERR_OK(status)) { - return status; - } - } - } - - tmp_dn = parent_dn; - - }; - - return ADS_ERROR(LDAP_SUCCESS); -} - -#endif /* HAVE_LDAP */ diff --git a/source3/libads/gpo_util.c b/source3/libads/gpo_util.c deleted file mode 100644 index a30df6e9eb..0000000000 --- a/source3/libads/gpo_util.c +++ /dev/null @@ -1,523 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * Group Policy Object Support - * Copyright (C) Guenther Deschner 2005 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include "includes.h" - -#ifdef HAVE_LDAP - -#define DEFAULT_DOMAIN_POLICY "Default Domain Policy" -#define DEFAULT_DOMAIN_CONTROLLERS_POLICY "Default Domain Controllers Policy" - -/* should we store a parsed guid ? */ -struct gpo_table { - const char *name; - const char *guid_string; -}; - -struct snapin_table { - const char *name; - const char *guid_string; - ADS_STATUS (*snapin_fn)(ADS_STRUCT *, TALLOC_CTX *mem_ctx, const char *, const char *); -}; - -#if 0 /* unused */ -static struct gpo_table gpo_default_policy[] = { - { DEFAULT_DOMAIN_POLICY, - "31B2F340-016D-11D2-945F-00C04FB984F9" }, - { DEFAULT_DOMAIN_CONTROLLERS_POLICY, - "6AC1786C-016F-11D2-945F-00C04fB984F9" }, - { NULL, NULL } -}; -#endif - -/* the following is seen in gPCMachineExtensionNames or gPCUserExtensionNames */ - -static struct gpo_table gpo_cse_extensions[] = { - { "Administrative Templates Extension", - "35378EAC-683F-11D2-A89A-00C04FBBCFA2" }, /* Registry Policy ? */ - { "Microsoft Disc Quota", - "3610EDA5-77EF-11D2-8DC5-00C04FA31A66" }, - { "EFS recovery", - "B1BE8D72-6EAC-11D2-A4EA-00C04F79F83A" }, - { "Folder Redirection", - "25537BA6-77A8-11D2-9B6C-0000F8080861" }, - { "IP Security", - "E437BC1C-AA7D-11D2-A382-00C04F991E27" }, - { "Internet Explorer Branding", - "A2E30F80-D7DE-11d2-BBDE-00C04F86AE3B" }, - { "QoS Packet Scheduler", - "426031c0-0b47-4852-b0ca-ac3d37bfcb39" }, - { "Scripts", - "42B5FAAE-6536-11D2-AE5A-0000F87571E3" }, - { "Security", - "827D319E-6EAC-11D2-A4EA-00C04F79F83A" }, - { "Software Installation", - "C6DC5466-785A-11D2-84D0-00C04FB169F7" }, - { "Wireless Group Policy", - "0ACDD40C-75AC-BAA0-BF6DE7E7FE63" }, - { NULL, NULL } -}; - -/* guess work */ -static struct snapin_table gpo_cse_snapin_extensions[] = { - { "Administrative Templates", - "0F6B957D-509E-11D1-A7CC-0000F87571E3", gpo_snapin_handler_none }, - { "Certificates", - "53D6AB1D-2488-11D1-A28C-00C04FB94F17", gpo_snapin_handler_none }, - { "EFS recovery policy processing", - "B1BE8D72-6EAC-11D2-A4EA-00C04F79F83A", gpo_snapin_handler_none }, - { "Folder Redirection policy processing", - "25537BA6-77A8-11D2-9B6C-0000F8080861", gpo_snapin_handler_none }, - { "Folder Redirection", - "88E729D6-BDC1-11D1-BD2A-00C04FB9603F", gpo_snapin_handler_none }, - { "Registry policy processing", - "35378EAC-683F-11D2-A89A-00C04FBBCFA2", gpo_snapin_handler_none }, - { "Remote Installation Services", - "3060E8CE-7020-11D2-842D-00C04FA372D4", gpo_snapin_handler_none }, - { "Security Settings", - "803E14A0-B4FB-11D0-A0D0-00A0C90F574B", gpo_snapin_handler_security_settings }, - { "Security policy processing", - "827D319E-6EAC-11D2-A4EA-00C04F79F83A", gpo_snapin_handler_security_settings }, - { "unknown", - "3060E8D0-7020-11D2-842D-00C04FA372D4", gpo_snapin_handler_none }, - { "unknown2", - "53D6AB1B-2488-11D1-A28C-00C04FB94F17", gpo_snapin_handler_none }, - { NULL, NULL, NULL } -}; - -static const char *name_to_guid_string(const char *name, struct gpo_table *table) -{ - int i; - - for (i = 0; table[i].name; i++) { - if (strequal(name, table[i].name)) { - return table[i].guid_string; - } - } - - return NULL; -} - -static const char *guid_string_to_name(const char *guid_string, struct gpo_table *table) -{ - int i; - - for (i = 0; table[i].guid_string; i++) { - if (strequal(guid_string, table[i].guid_string)) { - return table[i].name; - } - } - - return NULL; -} - -static const char *snapin_guid_string_to_name(const char *guid_string, - struct snapin_table *table) -{ - int i; - for (i = 0; table[i].guid_string; i++) { - if (strequal(guid_string, table[i].guid_string)) { - return table[i].name; - } - } - return NULL; -} - -#if 0 /* unused */ -static const char *default_gpo_name_to_guid_string(const char *name) -{ - return name_to_guid_string(name, gpo_default_policy); -} - -static const char *default_gpo_guid_string_to_name(const char *guid) -{ - return guid_string_to_name(guid, gpo_default_policy); -} -#endif - -const char *cse_gpo_guid_string_to_name(const char *guid) -{ - return guid_string_to_name(guid, gpo_cse_extensions); -} - -static const char *cse_gpo_name_to_guid_string(const char *name) -{ - return name_to_guid_string(name, gpo_cse_extensions); -} - -const char *cse_snapin_gpo_guid_string_to_name(const char *guid) -{ - return snapin_guid_string_to_name(guid, gpo_cse_snapin_extensions); -} - -void dump_gp_ext(struct GP_EXT *gp_ext) -{ - int lvl = 10; - int i; - - if (gp_ext == NULL) { - return; - } - - DEBUG(lvl,("---------------------\n\n")); - DEBUGADD(lvl,("name:\t\t\t%s\n", gp_ext->gp_extension)); - - for (i=0; i< gp_ext->num_exts; i++) { - - DEBUGADD(lvl,("extension:\t\t\t%s\n", gp_ext->extensions_guid[i])); - DEBUGADD(lvl,("extension (name):\t\t\t%s\n", gp_ext->extensions[i])); - - DEBUGADD(lvl,("snapin:\t\t\t%s\n", gp_ext->snapins_guid[i])); - DEBUGADD(lvl,("snapin (name):\t\t\t%s\n", gp_ext->snapins[i])); - } -} - -void dump_gpo(TALLOC_CTX *mem_ctx, struct GROUP_POLICY_OBJECT *gpo) -{ - int lvl = 1; - - if (gpo == NULL) { - return; - } - - DEBUG(lvl,("---------------------\n\n")); - - DEBUGADD(lvl,("name:\t\t\t%s\n", gpo->name)); - DEBUGADD(lvl,("displayname:\t\t%s\n", gpo->display_name)); - DEBUGADD(lvl,("version:\t\t%d (0x%08x)\n", gpo->version, gpo->version)); - DEBUGADD(lvl,("version_user:\t\t%d (0x%04x)\n", gpo->version_user, gpo->version_user)); - DEBUGADD(lvl,("version_machine:\t%d (0x%04x)\n", gpo->version_machine, gpo->version_machine)); - DEBUGADD(lvl,("filesyspath:\t\t%s\n", gpo->file_sys_path)); - DEBUGADD(lvl,("dspath:\t\t%s\n", gpo->ds_path)); - - DEBUGADD(lvl,("options:\t\t%d ", gpo->options)); - if (gpo->options & GPFLAGS_USER_SETTINGS_DISABLED) { - DEBUGADD(lvl,("GPFLAGS_USER_SETTINGS_DISABLED ")); - } - if (gpo->options & GPFLAGS_MACHINE_SETTINGS_DISABLED) { - DEBUGADD(lvl,("GPFLAGS_MACHINE_SETTINGS_DISABLED")); - } - DEBUGADD(lvl,("\n")); - - DEBUGADD(lvl,("link:\t\t\t%s\n", gpo->link)); - DEBUGADD(lvl,("link_type:\t\t%d ", gpo->link_type)); - switch (gpo->link_type) { - case GP_LINK_UNKOWN: - DEBUGADD(lvl,("GP_LINK_UNKOWN\n")); - break; - case GP_LINK_OU: - DEBUGADD(lvl,("GP_LINK_OU\n")); - break; - case GP_LINK_DOMAIN: - DEBUGADD(lvl,("GP_LINK_DOMAIN\n")); - break; - case GP_LINK_SITE: - DEBUGADD(lvl,("GP_LINK_SITE\n")); - break; - case GP_LINK_MACHINE: - DEBUGADD(lvl,("GP_LINK_MACHINE\n")); - break; - default: - break; - } - - if (gpo->machine_extensions) { - - struct GP_EXT gp_ext; - ADS_STATUS status; - - DEBUGADD(lvl,("machine_extensions:\t%s\n", gpo->machine_extensions)); - - status = ads_parse_gp_ext(mem_ctx, gpo->machine_extensions, &gp_ext); - if (!ADS_ERR_OK(status)) { - return; - } - dump_gp_ext(&gp_ext); - } - - if (gpo->user_extensions) { - - struct GP_EXT gp_ext; - ADS_STATUS status; - - DEBUGADD(lvl,("user_extensions:\t%s\n", gpo->user_extensions)); - - status = ads_parse_gp_ext(mem_ctx, gpo->user_extensions, &gp_ext); - if (!ADS_ERR_OK(status)) { - return; - } - dump_gp_ext(&gp_ext); - } -}; - -void dump_gplink(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, struct GP_LINK *gp_link) -{ - ADS_STATUS status; - int i; - int lvl = 10; - - if (gp_link == NULL) { - return; - } - - DEBUG(lvl,("---------------------\n\n")); - - DEBUGADD(lvl,("gplink: %s\n", gp_link->gp_link)); - DEBUGADD(lvl,("gpopts: %d ", gp_link->gp_opts)); - switch (gp_link->gp_opts) { - case GPOPTIONS_INHERIT: - DEBUGADD(lvl,("GPOPTIONS_INHERIT\n")); - break; - case GPOPTIONS_BLOCK_INHERITANCE: - DEBUGADD(lvl,("GPOPTIONS_BLOCK_INHERITANCE\n")); - break; - default: - break; - } - - DEBUGADD(lvl,("num links: %d\n", gp_link->num_links)); - - for (i = 0; i < gp_link->num_links; i++) { - - DEBUGADD(lvl,("---------------------\n\n")); - - DEBUGADD(lvl,("link: #%d\n", i + 1)); - DEBUGADD(lvl,("name: %s\n", gp_link->link_names[i])); - - DEBUGADD(lvl,("opt: %d ", gp_link->link_opts[i])); - if (gp_link->link_opts[i] & GPO_LINK_OPT_ENFORCED) { - DEBUGADD(lvl,("GPO_LINK_OPT_ENFORCED ")); - } - if (gp_link->link_opts[i] & GPO_LINK_OPT_DISABLED) { - DEBUGADD(lvl,("GPO_LINK_OPT_DISABLED")); - } - DEBUGADD(lvl,("\n")); - - if (ads != NULL && mem_ctx != NULL) { - - struct GROUP_POLICY_OBJECT gpo; - - status = ads_get_gpo(ads, mem_ctx, gp_link->link_names[i], NULL, NULL, &gpo); - if (!ADS_ERR_OK(status)) { - DEBUG(lvl,("get gpo for %s failed: %s\n", gp_link->link_names[i], ads_errstr(status))); - return; - } - dump_gpo(mem_ctx, &gpo); - } - } -} - -ADS_STATUS process_extension_with_snapin(ADS_STRUCT *ads, - TALLOC_CTX *mem_ctx, - const char *extension_guid, - const char *snapin_guid) -{ - int i; - - for (i=0; gpo_cse_snapin_extensions[i].guid_string; i++) { - - if (strcmp(gpo_cse_snapin_extensions[i].guid_string, snapin_guid) == 0) { - - return gpo_cse_snapin_extensions[i].snapin_fn(ads, mem_ctx, - extension_guid, snapin_guid); - } - } - - DEBUG(10,("process_extension_with_snapin: no snapin handler for extension %s (%s) found\n", - extension_guid, snapin_guid)); - - return ADS_ERROR(LDAP_SUCCESS); -} - -ADS_STATUS gpo_process_a_gpo(ADS_STRUCT *ads, - TALLOC_CTX *mem_ctx, - struct GROUP_POLICY_OBJECT *gpo, - const char *extension_guid, - uint32 flags) -{ - ADS_STATUS status; - struct GP_EXT gp_ext; - int i; - - if (flags & GPO_LIST_FLAG_MACHINE) { - - if (gpo->machine_extensions) { - - status = ads_parse_gp_ext(mem_ctx, gpo->machine_extensions, &gp_ext); - - if (!ADS_ERR_OK(status)) { - return status; - } - - } else { - /* nothing to apply */ - return ADS_ERROR(LDAP_SUCCESS); - } - - } else { - - if (gpo->user_extensions) { - - status = ads_parse_gp_ext(mem_ctx, gpo->user_extensions, &gp_ext); - - if (!ADS_ERR_OK(status)) { - return status; - } - } else { - /* nothing to apply */ - return ADS_ERROR(LDAP_SUCCESS); - } - } - - for (i=0; inext) { - - status = gpo_process_a_gpo(ads, mem_ctx, gpo, - extensions_guid, flags); - - if (!ADS_ERR_OK(status)) { - return status; - } - - } - - return ADS_ERROR(LDAP_SUCCESS); -} - -ADS_STATUS gpo_snapin_handler_none(ADS_STRUCT *ads, - TALLOC_CTX *mem_ctx, - const char *extension_guid, - const char *snapin_guid) -{ - DEBUG(10,("gpo_snapin_handler_none\n")); - - return ADS_ERROR(LDAP_SUCCESS); -} - -ADS_STATUS gpo_snapin_handler_security_settings(ADS_STRUCT *ads, - TALLOC_CTX *mem_ctx, - const char *extension_guid, - const char *snapin_guid) -{ - DEBUG(10,("gpo_snapin_handler_security_settings\n")); - - return ADS_ERROR(LDAP_SUCCESS); -} - -ADS_STATUS gpo_lockout_policy(ADS_STRUCT *ads, - TALLOC_CTX *mem_ctx, - const char *hostname, - SAM_UNK_INFO_12 *lockout_policy) -{ - return ADS_ERROR_NT(NT_STATUS_NOT_IMPLEMENTED); -} - -ADS_STATUS gpo_password_policy(ADS_STRUCT *ads, - TALLOC_CTX *mem_ctx, - const char *hostname, - SAM_UNK_INFO_1 *password_policy) -{ - ADS_STATUS status; - struct GROUP_POLICY_OBJECT *gpo_list; - const char *attrs[] = {"distinguishedName", "userAccountControl", NULL}; - char *filter, *dn; - LDAPMessage *res = NULL; - uint32 uac; - - filter = talloc_asprintf(mem_ctx, "(&(objectclass=user)(sAMAccountName=%s))", hostname); - if (filter == NULL) { - return ADS_ERROR(LDAP_NO_MEMORY); - } - - status = ads_do_search_all(ads, ads->config.bind_path, - LDAP_SCOPE_SUBTREE, - filter, attrs, &res); - - if (!ADS_ERR_OK(status)) { - return status; - } - - if (ads_count_replies(ads, res) != 1) { - ads_msgfree(ads, res); - return ADS_ERROR(LDAP_NO_SUCH_OBJECT); - } - - dn = ads_get_dn(ads, res); - if (dn == NULL) { - ads_msgfree(ads, res); - return ADS_ERROR(LDAP_NO_MEMORY); - } - - if (!ads_pull_uint32(ads, res, "userAccountControl", &uac)) { - ads_msgfree(ads, res); - ads_memfree(ads, dn); - return ADS_ERROR(LDAP_NO_MEMORY); - } - - ads_msgfree(ads, res); - - if (!(uac & UF_WORKSTATION_TRUST_ACCOUNT)) { - ads_memfree(ads, dn); - return ADS_ERROR(LDAP_NO_SUCH_OBJECT); - } - - status = ads_get_gpo_list(ads, mem_ctx, dn, GPO_LIST_FLAG_MACHINE, &gpo_list); - if (!ADS_ERR_OK(status)) { - ads_memfree(ads, dn); - return status; - } - - ads_memfree(ads, dn); - - status = gpo_process_gpo_list(ads, mem_ctx, &gpo_list, - cse_gpo_name_to_guid_string("Security"), - GPO_LIST_FLAG_MACHINE); - if (!ADS_ERR_OK(status)) { - return status; - } - - return ADS_ERROR(LDAP_SUCCESS); -} - -#endif /* HAVE_LDAP */ -- cgit From ac080e3184abcc177f9f8e8bf2f3537739b9e8ad Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 2 Oct 2006 12:06:49 +0000 Subject: r19039: Do not segfault in "net ads printer info" when a requested printserver does not exist. Guenther (This used to be commit 359315021df3a4dbfe5142e529e3efdbc49e405c) --- source3/libads/ldap_printer.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index 50233140f0..f5168b05af 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -41,8 +41,18 @@ servername)); return status; } + if (ads_count_replies(ads, *res) != 1) { + return ADS_ERROR(LDAP_NO_SUCH_OBJECT); + } srv_dn = ldap_get_dn(ads->ld, *res); + if (srv_dn == NULL) { + return ADS_ERROR(LDAP_NO_MEMORY); + } srv_cn = ldap_explode_dn(srv_dn, 1); + if (srv_cn == NULL) { + ldap_memfree(srv_dn); + return ADS_ERROR(LDAP_INVALID_DN_SYNTAX); + } ads_msgfree(ads, *res); asprintf(&s, "(cn=%s-%s)", srv_cn[0], printer); -- cgit From 424d7640b8d3a3e7f464ae429322b943985c11fe Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 13 Oct 2006 09:44:54 +0000 Subject: r19263: Be more accurate in telling what the sitename problem is in this DEBUG statement. Guenther (This used to be commit 62928734b820f512f940c1ed79048e14b322d060) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 6077231ae2..2b36d5575e 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -133,7 +133,7 @@ BOOL ads_sitename_match(ADS_STRUCT *ads) DEBUG(10,("ads_sitename_match: name %s match\n", ads->config.server_site_name)); return True; } - DEBUG(10,("ads_sitename_match: no match %s %s\n", + DEBUG(10,("ads_sitename_match: no match between server: %s and client: %s\n", ads->config.server_site_name ? ads->config.server_site_name : "NULL", ads->config.client_site_name ? ads->config.client_site_name : "NULL")); return False; -- cgit From 6b65a1c26dabfa8311592f7277c09d69e9b76226 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 1 Nov 2006 11:04:28 +0000 Subject: r19526: Fix minor memleak. Guenther (This used to be commit 61ebedc82ee7d7a98e2a52b0677d723a801ab30f) --- source3/libads/ldap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 2b36d5575e..6fbae51179 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1232,6 +1232,7 @@ ADS_STATUS ads_del_dn(ADS_STRUCT *ads, char *del_dn) } ret = ldap_delete_s(ads->ld, utf8_dn); + SAFE_FREE(utf8_dn); return ADS_ERROR(ret); } -- cgit From 31a63ab19f2a1f717db90d1164a8b696c625e739 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 1 Nov 2006 11:19:33 +0000 Subject: r19528: Fix container handling for "net ads user" and "net ads group" functions along with some memleaks. Guenther (This used to be commit 4bad52c5b3a983418d4216a2c3f5e04926e37e94) --- source3/libads/ldap.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 6fbae51179..1e726f5e55 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1299,6 +1299,7 @@ char *ads_default_ou_string(ADS_STRUCT *ads, const char *wknguid) SAFE_FREE(base); if (ads_count_replies(ads, res) != 1) { + ads_msgfree(ads, res); return NULL; } @@ -1314,7 +1315,7 @@ char *ads_default_ou_string(ADS_STRUCT *ads, const char *wknguid) new_ln = wkn_ln - bind_ln; - ret = wkn_dn_exp[0]; + ret = SMB_STRDUP(wkn_dn_exp[0]); for (i=1; i < new_ln; i++) { char *s; @@ -1323,6 +1324,7 @@ char *ads_default_ou_string(ADS_STRUCT *ads, const char *wknguid) free(s); } + ads_msgfree(ads, res); ads_memfree(ads, wkn_dn); ldap_value_free(wkn_dn_exp); ldap_value_free(bind_dn_exp); -- cgit From e513fb27d61d31cdc1a0e723c5345a659cc2caf2 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 9 Nov 2006 10:16:38 +0000 Subject: r19646: Fix memleak in the default_ou_string handling. Thanks to David Hu . Fixes #4212. Guenther (This used to be commit 4ec896cdbe441b17d91895a50ac9be61efe2f9c1) --- source3/libads/ldap.c | 48 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 11 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 1e726f5e55..927b86fe93 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1276,8 +1276,8 @@ char *ads_ou_string(ADS_STRUCT *ads, const char *org_unit) char *ads_default_ou_string(ADS_STRUCT *ads, const char *wknguid) { ADS_STATUS status; - LDAPMessage *res; - char *base, *wkn_dn, *ret, **wkn_dn_exp, **bind_dn_exp; + LDAPMessage *res = NULL; + char *base, *wkn_dn, *ret = NULL, **wkn_dn_exp, **bind_dn_exp; const char *attrs[] = {"distinguishedName", NULL}; int new_ln, wkn_ln, bind_ln, i; @@ -1293,20 +1293,28 @@ char *ads_default_ou_string(ADS_STRUCT *ads, const char *wknguid) status = ads_search_dn(ads, &res, base, attrs); if (!ADS_ERR_OK(status)) { DEBUG(1,("Failed while searching for: %s\n", base)); - SAFE_FREE(base); - return NULL; + goto out; } - SAFE_FREE(base); if (ads_count_replies(ads, res) != 1) { - ads_msgfree(ads, res); - return NULL; + goto out; } /* substitute the bind-path from the well-known-guid-search result */ wkn_dn = ads_get_dn(ads, res); + if (!wkn_dn) { + goto out; + } + wkn_dn_exp = ldap_explode_dn(wkn_dn, 0); + if (!wkn_dn_exp) { + goto out; + } + bind_dn_exp = ldap_explode_dn(ads->config.bind_path, 0); + if (!bind_dn_exp) { + goto out; + } for (wkn_ln=0; wkn_dn_exp[wkn_ln]; wkn_ln++) ; @@ -1316,18 +1324,36 @@ char *ads_default_ou_string(ADS_STRUCT *ads, const char *wknguid) new_ln = wkn_ln - bind_ln; ret = SMB_STRDUP(wkn_dn_exp[0]); + if (!ret) { + goto out; + } for (i=1; i < new_ln; i++) { - char *s; - asprintf(&s, "%s,%s", ret, wkn_dn_exp[i]); + char *s = NULL; + + if (asprintf(&s, "%s,%s", ret, wkn_dn_exp[i]) == -1) { + SAFE_FREE(ret); + goto out; + } + + SAFE_FREE(ret); ret = SMB_STRDUP(s); free(s); + if (!ret) { + goto out; + } } + out: + SAFE_FREE(base); ads_msgfree(ads, res); ads_memfree(ads, wkn_dn); - ldap_value_free(wkn_dn_exp); - ldap_value_free(bind_dn_exp); + if (wkn_dn_exp) { + ldap_value_free(wkn_dn_exp); + } + if (bind_dn_exp) { + ldap_value_free(bind_dn_exp); + } return ret; } -- cgit From 61a38bd4b83b7f72b479e84daa5ea89164a92f85 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 10 Nov 2006 12:42:50 +0000 Subject: r19651: Fix interesting bug with the automatic site coverage in Active Directory: When having DC-less sites, AD assigns DCs from other sites to that site that does not have it's own DC. The most reliable way for us to identify the nearest DC - in that and all other cases - is the closest_dc flag in the CLDAP reply. Guenther (This used to be commit ff004f7284cb047e738ba3d3ad6602e8aa84e883) --- source3/libads/ldap.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 927b86fe93..5dcc3c33ba 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -139,6 +139,30 @@ BOOL ads_sitename_match(ADS_STRUCT *ads) return False; } +/********************************************** + Is this the closest DC ? +**********************************************/ + +BOOL ads_closest_dc(ADS_STRUCT *ads) +{ + if (ads->config.flags & ADS_CLOSEST) { + DEBUG(10,("ads_closest_dc: ADS_CLOSEST flag set\n")); + return True; + } + + /* not sure if this can ever happen */ + if (ads_sitename_match(ads)) { + DEBUG(10,("ads_closest_dc: ADS_CLOSEST flag not set but sites match\n")); + return True; + } + + DEBUG(10,("ads_closest_dc: %s is not the closest DC\n", + ads->config.ldap_server_name)); + + return False; +} + + /* try a connection to a given ldap server, returning True and setting the servers IP in the ads struct if successful @@ -392,7 +416,7 @@ got_connection: } /* cache the successful connection for workgroup and realm */ - if (ads_sitename_match(ads)) { + if (ads_closest_dc(ads)) { saf_store( ads->server.workgroup, inet_ntoa(ads->ldap_ip)); saf_store( ads->server.realm, inet_ntoa(ads->ldap_ip)); } -- cgit From bae1fcd20fb01942b40fddf7893d54063cf5ac95 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 13 Nov 2006 10:34:59 +0000 Subject: r19687: Fix uninitialized variables found by Coverity (and gcc -O1... ;-)) Volker (This used to be commit b7dc9b81696aa5434419c5378a47b41c6dee3dfa) --- source3/libads/ldap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 5dcc3c33ba..f65ae02ede 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1301,7 +1301,8 @@ char *ads_default_ou_string(ADS_STRUCT *ads, const char *wknguid) { ADS_STATUS status; LDAPMessage *res = NULL; - char *base, *wkn_dn, *ret = NULL, **wkn_dn_exp, **bind_dn_exp; + char *base, *wkn_dn = NULL, *ret = NULL, **wkn_dn_exp = NULL, + **bind_dn_exp = NULL; const char *attrs[] = {"distinguishedName", NULL}; int new_ln, wkn_ln, bind_ln, i; -- cgit From dc06fda6c7b87a3e2a8521269f4fca3f70969281 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Tue, 12 Dec 2006 20:27:01 +0000 Subject: r20132: get rid of defined but not used warning - static function only used inside the #ifdef HAVE_KRB5 (This used to be commit c6cdf76c5809b4a4b145acb7dd4a695aaf7fcd28) --- source3/libads/sasl.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index c3f496938a..7d1fd0d1a8 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -136,6 +136,7 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) return ADS_ERROR(rc); } +#ifdef HAVE_KRB5 /* perform a LDAP/SASL/SPNEGO/KRB5 bind */ @@ -165,6 +166,7 @@ static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *princip return ADS_ERROR(rc); } +#endif /* this performs a SASL/SPNEGO bind -- cgit From db7bf9a6b6754b604ee44d28c564bab10c7b98a7 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 14 Dec 2006 17:00:10 +0000 Subject: r20173: DNS update fixes: * Fix DNS updates for multi-homed hosts * Child domains often don't have an NS record in DNS so we have to fall back to looking up the the NS records for the forest root. * Fix compile warning caused by mismatched 'struct in_addr' and 'in_addr_t' parameters called to DoDNSUpdate() (This used to be commit 3486acd3c3ebefae8f98dcc72d1c3d6b06fffcc7) --- source3/libads/ads_struct.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index 130d86b8dc..545995ddcc 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -75,6 +75,28 @@ char *ads_build_dn(const char *realm) return ads_build_path(realm, ".", "dc=", 0); } +/* return a DNS name in the for aa.bb.cc from the DN + "dc=AA,dc=BB,dc=CC". caller must free +*/ +char *ads_build_domain(const char *dn) +{ + char *dnsdomain = NULL; + + /* result should always be shorter than the DN */ + + if ( (dnsdomain = SMB_STRDUP( dn )) == NULL ) { + DEBUG(0,("ads_build_domain: malloc() failed!\n")); + return NULL; + } + + strlower_m( dnsdomain ); + all_string_sub( dnsdomain, "dc=", "", 0); + all_string_sub( dnsdomain, ",", ".", 0 ); + + return dnsdomain; +} + + #ifndef LDAP_PORT #define LDAP_PORT 389 -- cgit From 2d349000887670c1127d354e9ce2b53284caf7f9 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 20 Dec 2006 10:54:09 +0000 Subject: r20273: Map KRB5_KDCREP_SKEW to NT_STATUS_TIME_DIFFERENCE_AT_DC. This gives much nicer error messages when failing to join due to clock skew. Guenther (This used to be commit 5c5a7611029ff1b630c53d4660578e188acf97f5) --- source3/libads/krb5_errs.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libads') diff --git a/source3/libads/krb5_errs.c b/source3/libads/krb5_errs.c index 38d34f8676..a4a3bd3adb 100644 --- a/source3/libads/krb5_errs.c +++ b/source3/libads/krb5_errs.c @@ -50,6 +50,7 @@ static const struct { {KRB5KRB_AP_ERR_BAD_INTEGRITY, NT_STATUS_LOGON_FAILURE}, {KRB5KRB_AP_ERR_MODIFIED, NT_STATUS_LOGON_FAILURE}, {KRB5KRB_AP_ERR_SKEW, NT_STATUS_TIME_DIFFERENCE_AT_DC}, + {KRB5_KDCREP_SKEW, NT_STATUS_TIME_DIFFERENCE_AT_DC}, {KRB5KRB_AP_ERR_TKT_EXPIRED, NT_STATUS_LOGON_FAILURE}, {KRB5KRB_ERR_GENERIC, NT_STATUS_UNSUCCESSFUL}, #if defined(KRB5KRB_ERR_RESPONSE_TOO_BIG) -- cgit From 76cdf68ee9f4982f1b847023818641cf4603dfd1 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 29 Dec 2006 09:18:06 +0000 Subject: r20403: Cleaning out my Samba 3.0 tree: As discussed with jerry at the CIFS conf: overriding the administrator's wishes from the krb5.conf has only every given me segfaults. We suggest leaving this up to the defaults from the libraries anyway. Andrew Bartlett (This used to be commit 0b72c04906b1c25e80b217a8f34fd3a8e756b9ca) --- source3/libads/sasl.c | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 7d1fd0d1a8..d1699dbab7 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -42,7 +42,6 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) if (!NT_STATUS_IS_OK(nt_status = ntlmssp_client_start(&ntlmssp_state))) { return ADS_ERROR_NT(nt_status); } - ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SIGN; if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, ads->auth.user_name))) { return ADS_ERROR_NT(nt_status); @@ -283,12 +282,6 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) ADS_STATUS status; krb5_principal principal; krb5_context ctx = NULL; - krb5_enctype enc_types[] = { -#ifdef ENCTYPE_ARCFOUR_HMAC - ENCTYPE_ARCFOUR_HMAC, -#endif - ENCTYPE_DES_CBC_MD5, - ENCTYPE_NULL}; gss_OID_desc nt_principal = {10, CONST_DISCARD(char *, "\052\206\110\206\367\022\001\002\002\002")}; @@ -301,10 +294,6 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) if (!ADS_ERR_OK(status)) { return status; } - status = ADS_ERROR_KRB5(krb5_set_default_tgs_ktypes(ctx, enc_types)); - if (!ADS_ERR_OK(status)) { - return status; - } status = ADS_ERROR_KRB5(smb_krb5_parse_name(ctx, sname, &principal)); if (!ADS_ERR_OK(status)) { return status; -- cgit From 725cb5d7c9e651af7a5739774bdaff69ea5a61a9 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 2 Jan 2007 21:29:09 +0000 Subject: r20486: Always upper case the "host/" entry in the keytab file so apps will know which one to look for, (This used to be commit d4a5dc3ad5f56a5f741424ecc4fffa0ef39bdc67) --- source3/libads/kerberos_keytab.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c index 80d11d434b..4b640151d3 100644 --- a/source3/libads/kerberos_keytab.c +++ b/source3/libads/kerberos_keytab.c @@ -530,13 +530,18 @@ int ads_keytab_create_default(ADS_STRUCT *ads) } /* now add the userPrincipalName and sAMAccountName entries */ - + if ( (sam_account_name = ads_get_samaccountname( ads, ctx, machine_name)) == NULL ) { DEBUG(0,("ads_keytab_add_entry: unable to determine machine account's name in AD!\n")); TALLOC_FREE( ctx ); return -1; } + /* upper case the sAMAccountName to make it easier for apps to + know what case to use in the keytab file */ + + strupper_m( sam_account_name ); + if ( (ret = ads_keytab_add_entry(ads, sam_account_name )) != 0 ) { DEBUG(1,("ads_keytab_create_default: ads_keytab_add_entry failed while adding sAMAccountName (%s)\n", sam_account_name)); -- cgit From d3fc370fb9e32b881bb6c626ac525246af665ea4 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 2 Jan 2007 21:45:12 +0000 Subject: r20487: Remove the unused dn2ad_canonical() call (This used to be commit 86e6ae6a9fe2a6fdaeeb503653a312662c7f50e9) --- source3/libads/ldap.c | 18 ------------------ 1 file changed, 18 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index f65ae02ede..c263e8e133 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -978,21 +978,6 @@ void ads_memfree(ADS_STRUCT *ads, void *mem) return unix_dn; } -/** - * Get a canonical dn from search results - * @param ads connection to ads server - * @param msg Search result - * @return dn string - **/ - char *ads_get_dn_canonical(ADS_STRUCT *ads, LDAPMessage *msg) -{ -#ifdef HAVE_LDAP_DN2AD_CANONICAL - return ldap_dn2ad_canonical(ads_get_dn(ads, msg)); -#else - return NULL; -#endif -} - /** * Get the parent from a dn * @param dn the dn to return the parent from @@ -2938,8 +2923,6 @@ ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *machine_name, } #endif -#ifdef HAVE_LDAP - /** * Delete a machine from the realm * @param ads connection to ads server @@ -3059,6 +3042,5 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) SAFE_FREE(host); return status; } -#endif #endif -- cgit From f3a85fb152c0cb07ae1c096f06488f88c4c9d741 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 4 Jan 2007 23:41:16 +0000 Subject: r20536: In the offline PAM session close case the attempt to delete a non-existing krb5 credential cache should not generate an error. Guenther (This used to be commit 11c6f573af5c1d3387e60f3fc44b00e28cd87813) --- source3/libads/krb5_errs.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/krb5_errs.c b/source3/libads/krb5_errs.c index a4a3bd3adb..89cfc2d143 100644 --- a/source3/libads/krb5_errs.c +++ b/source3/libads/krb5_errs.c @@ -56,6 +56,8 @@ static const struct { #if defined(KRB5KRB_ERR_RESPONSE_TOO_BIG) {KRB5KRB_ERR_RESPONSE_TOO_BIG, NT_STATUS_PROTOCOL_UNREACHABLE}, #endif + {KRB5_CC_NOTFOUND, NT_STATUS_NO_SUCH_FILE}, + {KRB5_FCC_NOFILE, NT_STATUS_NO_SUCH_FILE}, {KRB5KDC_ERR_NONE, NT_STATUS_OK}, {0, NT_STATUS_OK} }; -- cgit From bfd099e148ed97394bc858e746a1a998a71ac43c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 17 Jan 2007 18:25:35 +0000 Subject: r20857: Silence gives assent :-). Checking in the fix for site support in a network where many DC's are down. I heard via Volker there is still a bug w.r.t the wrong site being chosen with trusted domains but we'll have to layer that fix on top of this. Gd - complain if this doesn't work for you. Jeremy. (This used to be commit 97e248f89ac6548274f03f2ae7583a255da5ddb3) --- source3/libads/dns.c | 10 +++----- source3/libads/kerberos.c | 65 +++++++++++++++++++++++++++++++++++++---------- source3/libads/ldap.c | 19 ++++++++++++-- 3 files changed, 72 insertions(+), 22 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/dns.c b/source3/libads/dns.c index c8b3f29507..b67d802bdc 100644 --- a/source3/libads/dns.c +++ b/source3/libads/dns.c @@ -673,16 +673,16 @@ NTSTATUS ads_dns_query_internal(TALLOC_CTX *ctx, } /******************************************************************** - Query for AD DC's. Transparently use sitename. + Query for AD DC's. ********************************************************************/ NTSTATUS ads_dns_query_dcs(TALLOC_CTX *ctx, const char *realm, + const char *sitename, struct dns_rr_srv **dclist, int *numdcs ) { NTSTATUS status; - char *sitename = sitename_fetch(); status = ads_dns_query_internal(ctx, "_ldap", realm, sitename, dclist, numdcs); @@ -691,23 +691,22 @@ NTSTATUS ads_dns_query_dcs(TALLOC_CTX *ctx, status = ads_dns_query_internal(ctx, "_ldap", realm, NULL, dclist, numdcs); } - SAFE_FREE(sitename); return status; } /******************************************************************** - Query for AD KDC's. Transparently use sitename. + Query for AD KDC's. Even if our underlying kerberos libraries are UDP only, this is pretty safe as it's unlikely that a KDC supports TCP and not UDP. ********************************************************************/ NTSTATUS ads_dns_query_kdcs(TALLOC_CTX *ctx, const char *realm, + const char *sitename, struct dns_rr_srv **dclist, int *numdcs ) { NTSTATUS status; - char *sitename = sitename_fetch(); status = ads_dns_query_internal(ctx, "_kerberos", realm, sitename, dclist, numdcs); @@ -716,6 +715,5 @@ NTSTATUS ads_dns_query_kdcs(TALLOC_CTX *ctx, status = ads_dns_query_internal(ctx, "_kerberos", realm, NULL, dclist, numdcs); } - SAFE_FREE(sitename); return status; } diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 76866a8093..95eed6fe27 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -470,10 +470,11 @@ int kerberos_kinit_password(const char *principal, Does DNS queries. ************************************************************************/ -static char *get_kdc_ip_string(char *mem_ctx, const char *realm, struct in_addr primary_ip) +static char *get_kdc_ip_string(char *mem_ctx, const char *realm, const char *sitename, struct in_addr primary_ip) { - struct ip_service *ip_srv; - int count, i; + struct ip_service *ip_srv_site; + struct ip_service *ip_srv_nonsite; + int count_site, count_nonsite, i; char *kdc_str = talloc_asprintf(mem_ctx, "\tkdc = %s\n", inet_ntoa(primary_ip)); @@ -481,26 +482,61 @@ static char *get_kdc_ip_string(char *mem_ctx, const char *realm, struct in_addr return NULL; } - if (!NT_STATUS_IS_OK(get_kdc_list(realm, &ip_srv, &count))) { - DEBUG(10,("get_kdc_ip_string: get_kdc_list failed. Returning %s\n", - kdc_str )); - return kdc_str; + /* Get the KDC's only in this site. */ + + get_kdc_list(realm, sitename, &ip_srv_site, &count_site); + + for (i = 0; i < count_site; i++) { + if (ip_equal(ip_srv_site[i].ip, primary_ip)) { + continue; + } + /* Append to the string - inefficient but not done often. */ + kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n", + kdc_str, inet_ntoa(ip_srv_site[i].ip)); + if (!kdc_str) { + SAFE_FREE(ip_srv_site); + return NULL; + } } - for (i = 0; i < count; i++) { - if (ip_equal(ip_srv[i].ip, primary_ip)) { + /* Get all KDC's. */ + + get_kdc_list(realm, NULL, &ip_srv_nonsite, &count_nonsite); + + for (i = 0; i < count_nonsite; i++) { + int j; + + if (ip_equal(ip_srv_nonsite[i].ip, primary_ip)) { + continue; + } + + /* Ensure this isn't an IP already seen (YUK! this is n*n....) */ + for (j = 0; j < count_site; j++) { + if (ip_equal(ip_srv_nonsite[i].ip, ip_srv_site[j].ip)) { + break; + } + /* As the lists are sorted we can break early if nonsite > site. */ + if (ip_service_compare(&ip_srv_nonsite[i], &ip_srv_site[j]) > 0) { + break; + } + } + if (j != i) { continue; } + /* Append to the string - inefficient but not done often. */ kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n", - kdc_str, inet_ntoa(ip_srv[i].ip)); + kdc_str, inet_ntoa(ip_srv_nonsite[i].ip)); if (!kdc_str) { - SAFE_FREE(ip_srv); + SAFE_FREE(ip_srv_site); + SAFE_FREE(ip_srv_nonsite); return NULL; } } - SAFE_FREE(ip_srv); + + SAFE_FREE(ip_srv_site); + SAFE_FREE(ip_srv_nonsite); DEBUG(10,("get_kdc_ip_string: Returning %s\n", kdc_str )); @@ -515,7 +551,8 @@ static char *get_kdc_ip_string(char *mem_ctx, const char *realm, struct in_addr run as root or will fail (which is a good thing :-). ************************************************************************/ -BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *domain, struct in_addr ip) +BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *domain, + const char *sitename, struct in_addr ip) { char *dname = talloc_asprintf(NULL, "%s/smb_krb5", lp_lockdir()); char *tmpname = NULL; @@ -556,7 +593,7 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do realm_upper = talloc_strdup(fname, realm); strupper_m(realm_upper); - kdc_ip_string = get_kdc_ip_string(dname, realm, ip); + kdc_ip_string = get_kdc_ip_string(dname, realm, sitename, ip); if (!kdc_ip_string) { TALLOC_FREE(dname); return False; diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index c263e8e133..2ceae4d957 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -249,6 +249,7 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads) pstring realm; BOOL got_realm = False; BOOL use_own_domain = False; + char *sitename = sitename_fetch(); NTSTATUS status = NT_STATUS_UNSUCCESSFUL; /* if the realm and workgroup are both empty, assume they are ours */ @@ -279,6 +280,7 @@ again: } if ( !c_realm || !*c_realm ) { + SAFE_FREE(sitename); DEBUG(0,("ads_find_dc: no realm or workgroup! Don't know what to do\n")); return NT_STATUS_INVALID_PARAMETER; /* rather need MISSING_PARAMETER ... */ } @@ -289,7 +291,7 @@ again: DEBUG(6,("ads_find_dc: looking for %s '%s'\n", (got_realm ? "realm" : "domain"), realm)); - status = get_sorted_dc_list(realm, &ip_list, &count, got_realm); + status = get_sorted_dc_list(realm, sitename, &ip_list, &count, got_realm); if (!NT_STATUS_IS_OK(status)) { /* fall back to netbios if we can */ if ( got_realm && !lp_disable_netbios() ) { @@ -331,6 +333,7 @@ again: if ( ads_try_connect(ads, server) ) { SAFE_FREE(ip_list); + SAFE_FREE(sitename); return NT_STATUS_OK; } @@ -339,7 +342,19 @@ again: } SAFE_FREE(ip_list); - + + /* In case we failed to contact one of our closest DC on our site we + * need to try to find another DC, retry with a site-less SRV DNS query + * - Guenther */ + + if (sitename) { + DEBUG(1,("ads_find_dc: failed to find a valid DC on our site (%s), " + "trying to find another DC\n", sitename)); + SAFE_FREE(sitename); + namecache_delete(realm, 0x1C); + goto again; + } + return NT_STATUS_NO_LOGON_SERVERS; } -- cgit From f3ad8bb00acf680863902721c57091d2bf622b72 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 17 Jan 2007 19:11:45 +0000 Subject: r20860: Adding some small tweaks. When we have no sitename, there is no need to ask for the list of DCs twice. Guenther (This used to be commit a9baf27e1348dd6dadd7a2fafdf9c269087b80ac) --- source3/libads/kerberos.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 95eed6fe27..d35b59f4cd 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -484,18 +484,21 @@ static char *get_kdc_ip_string(char *mem_ctx, const char *realm, const char *sit /* Get the KDC's only in this site. */ - get_kdc_list(realm, sitename, &ip_srv_site, &count_site); + if (sitename) { - for (i = 0; i < count_site; i++) { - if (ip_equal(ip_srv_site[i].ip, primary_ip)) { - continue; - } - /* Append to the string - inefficient but not done often. */ - kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n", - kdc_str, inet_ntoa(ip_srv_site[i].ip)); - if (!kdc_str) { - SAFE_FREE(ip_srv_site); - return NULL; + get_kdc_list(realm, sitename, &ip_srv_site, &count_site); + + for (i = 0; i < count_site; i++) { + if (ip_equal(ip_srv_site[i].ip, primary_ip)) { + continue; + } + /* Append to the string - inefficient but not done often. */ + kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n", + kdc_str, inet_ntoa(ip_srv_site[i].ip)); + if (!kdc_str) { + SAFE_FREE(ip_srv_site); + return NULL; + } } } -- cgit From a99840e59ee4bd27fd4f2cf8b465dd0f215ea067 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 17 Jan 2007 19:20:11 +0000 Subject: r20862: When in disconnected mode there is no need to try a fallback to a site less DNS query. This speeds up offline detection slightly. Guenther (This used to be commit eda76ecf07a4d2f9bb5544e2c031cfad14d93e85) --- source3/libads/dns.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/dns.c b/source3/libads/dns.c index b67d802bdc..bd280fea62 100644 --- a/source3/libads/dns.c +++ b/source3/libads/dns.c @@ -291,6 +291,12 @@ static NTSTATUS dns_send_req( TALLOC_CTX *ctx, const char *name, int q_type, if ( (resp_len = res_query(name, C_IN, q_type, buffer, buf_len)) < 0 ) { DEBUG(3,("ads_dns_lookup_srv: Failed to resolve %s (%s)\n", name, strerror(errno))); TALLOC_FREE( buffer ); + if (errno == ETIMEDOUT) { + return NT_STATUS_IO_TIMEOUT; + } + if (errno == ECONNREFUSED) { + return NT_STATUS_CONNECTION_REFUSED; + } return NT_STATUS_UNSUCCESSFUL; } } while ( buf_len < resp_len && resp_len < MAX_DNS_PACKET_SIZE ); @@ -686,6 +692,12 @@ NTSTATUS ads_dns_query_dcs(TALLOC_CTX *ctx, status = ads_dns_query_internal(ctx, "_ldap", realm, sitename, dclist, numdcs); + + if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT) || + NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_REFUSED)) { + return status; + } + if (sitename && !NT_STATUS_IS_OK(status)) { /* Sitename DNS query may have failed. Try without. */ status = ads_dns_query_internal(ctx, "_ldap", realm, NULL, @@ -710,6 +722,12 @@ NTSTATUS ads_dns_query_kdcs(TALLOC_CTX *ctx, status = ads_dns_query_internal(ctx, "_kerberos", realm, sitename, dclist, numdcs); + + if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT) || + NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_REFUSED)) { + return status; + } + if (sitename && !NT_STATUS_IS_OK(status)) { /* Sitename DNS query may have failed. Try without. */ status = ads_dns_query_internal(ctx, "_kerberos", realm, NULL, -- cgit From e9c294b926c0b831fd936194342ec0564f935798 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 18 Jan 2007 09:58:57 +0000 Subject: r20874: We need to distinguish client sitenames per realm. We were overwriting the stored client sitename with the sitename from each sucessfull CLDAP connection. Guenther (This used to be commit 6a13e878b5d299cb3b3d7cb33ee0d51089d9228d) --- source3/libads/dns.c | 71 +++++++++++++++++++++++++++++++++++++++++---------- source3/libads/ldap.c | 10 +++++--- 2 files changed, 63 insertions(+), 18 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/dns.c b/source3/libads/dns.c index bd280fea62..b405d29d96 100644 --- a/source3/libads/dns.c +++ b/source3/libads/dns.c @@ -577,7 +577,19 @@ NTSTATUS ads_dns_lookup_ns( TALLOC_CTX *ctx, const char *dnsdomain, struct dns_r Store and fetch the AD client sitename. ****************************************************************************/ -#define SITENAME_KEY "AD_SITENAME" +#define SITENAME_KEY "AD_SITENAME/DOMAIN/%s" + +static char *sitename_key(const char *realm) +{ + char *keystr; + + if (asprintf(&keystr, SITENAME_KEY, strupper_static(realm)) == -1) { + return NULL; + } + + return keystr; +} + /**************************************************************************** Store the AD client sitename. @@ -586,26 +598,37 @@ NTSTATUS ads_dns_lookup_ns( TALLOC_CTX *ctx, const char *dnsdomain, struct dns_r as this isn't a valid DNS name. ****************************************************************************/ -BOOL sitename_store(const char *sitename) +BOOL sitename_store(const char *realm, const char *sitename) { time_t expire; BOOL ret = False; + char *key; if (!gencache_init()) { return False; } + + if (!realm || (strlen(realm) == 0)) { + DEBUG(0,("no realm\n")); + return False; + } + key = sitename_key(realm); + if (!sitename || (sitename && !*sitename)) { DEBUG(5,("sitename_store: deleting empty sitename!\n")); - return gencache_del(SITENAME_KEY); + ret = gencache_del(sitename_key(realm)); + SAFE_FREE(key); + return ret; } expire = get_time_t_max(); /* Store indefinately. */ - DEBUG(10,("sitename_store: sitename = [%s], expire = [%u]\n", - sitename, (unsigned int)expire )); + DEBUG(10,("sitename_store: realm = [%s], sitename = [%s], expire = [%u]\n", + realm, sitename, (unsigned int)expire )); - ret = gencache_set( SITENAME_KEY, sitename, expire ); + ret = gencache_set( key, sitename, expire ); + SAFE_FREE(key); return ret; } @@ -614,22 +637,34 @@ BOOL sitename_store(const char *sitename) Caller must free. ****************************************************************************/ -char *sitename_fetch(void) +char *sitename_fetch(const char *realm) { char *sitename = NULL; time_t timeout; BOOL ret = False; + const char *query_realm; + char *key; if (!gencache_init()) { return False; } - - ret = gencache_get( SITENAME_KEY, &sitename, &timeout ); + + if (!realm || (strlen(realm) == 0)) { + query_realm = lp_realm(); + } else { + query_realm = realm; + } + + key = sitename_key(query_realm); + + ret = gencache_get( key, &sitename, &timeout ); + SAFE_FREE(key); if ( !ret ) { - DEBUG(5,("sitename_fetch: No stored sitename\n")); + DEBUG(5,("sitename_fetch: No stored sitename for %s\n", + query_realm)); } else { - DEBUG(5,("sitename_fetch: Returning sitename \"%s\"\n", - sitename )); + DEBUG(5,("sitename_fetch: Returning sitename for %s: \"%s\"\n", + query_realm, sitename )); } return sitename; } @@ -638,10 +673,18 @@ char *sitename_fetch(void) Did the sitename change ? ****************************************************************************/ -BOOL stored_sitename_changed(const char *sitename) +BOOL stored_sitename_changed(const char *realm, const char *sitename) { BOOL ret = False; - char *new_sitename = sitename_fetch(); + + char *new_sitename; + + if (!realm || (strlen(realm) == 0)) { + DEBUG(0,("no realm\n")); + return False; + } + + new_sitename = sitename_fetch(realm); if (sitename && new_sitename && !strequal(sitename, new_sitename)) { ret = True; diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 2ceae4d957..4802f79d3e 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -230,7 +230,7 @@ BOOL ads_try_connect(ADS_STRUCT *ads, const char *server ) SAFE_FREE(srv); /* Store our site name. */ - sitename_store( cldap_reply.client_site_name ); + sitename_store( cldap_reply.domain, cldap_reply.client_site_name ); return True; } @@ -249,7 +249,7 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads) pstring realm; BOOL got_realm = False; BOOL use_own_domain = False; - char *sitename = sitename_fetch(); + char *sitename; NTSTATUS status = NT_STATUS_UNSUCCESSFUL; /* if the realm and workgroup are both empty, assume they are ours */ @@ -268,7 +268,6 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads) if (c_realm && *c_realm) got_realm = True; -again: /* we need to try once with the realm name and fallback to the netbios domain name if we fail (if netbios has not been disabled */ @@ -280,7 +279,6 @@ again: } if ( !c_realm || !*c_realm ) { - SAFE_FREE(sitename); DEBUG(0,("ads_find_dc: no realm or workgroup! Don't know what to do\n")); return NT_STATUS_INVALID_PARAMETER; /* rather need MISSING_PARAMETER ... */ } @@ -288,6 +286,10 @@ again: pstrcpy( realm, c_realm ); + sitename = sitename_fetch(realm); + + again: + DEBUG(6,("ads_find_dc: looking for %s '%s'\n", (got_realm ? "realm" : "domain"), realm)); -- cgit From 9d19e5294042e4de2c0eb70ee8b17993ebce211d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 Jan 2007 19:18:43 +0000 Subject: r20880: Fix memory leak in new sitename code. You got *really* close Guenther, then you forgot to use "key" :-) :-). Jeremy. (This used to be commit 56842b59d00d531b0c9c22639603dc721eab50b4) --- source3/libads/dns.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/dns.c b/source3/libads/dns.c index b405d29d96..008266ea0b 100644 --- a/source3/libads/dns.c +++ b/source3/libads/dns.c @@ -617,7 +617,7 @@ BOOL sitename_store(const char *realm, const char *sitename) if (!sitename || (sitename && !*sitename)) { DEBUG(5,("sitename_store: deleting empty sitename!\n")); - ret = gencache_del(sitename_key(realm)); + ret = gencache_del(key); SAFE_FREE(key); return ret; } -- cgit From b9b26be1744b792a54f0a77af140237b4dc5a870 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 24 Jan 2007 01:48:08 +0000 Subject: r20986: Commit the prototype of the nss_info plugin interface. This allows a provider to supply the homedirectory, etc... attributes for a user without requiring support in core winbindd code. The idmap_ad.c module has been modified to provide the idmap 'ad' library as well as the rfc2307 and sfu "winbind nss info" support. The SID/id mapping is working in idmap_ad but the nss_info still has a few quirks that I'm in the process of resolving. (This used to be commit aaec0115e2c96935499052d9a637a20c6445986e) --- source3/libads/ads_struct.c | 6 ---- source3/libads/ldap_schema.c | 77 ++++++++++++++++++-------------------------- 2 files changed, 32 insertions(+), 51 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index 545995ddcc..05f066c9fa 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -161,12 +161,6 @@ void ads_destroy(ADS_STRUCT **ads) SAFE_FREE((*ads)->config.server_site_name); SAFE_FREE((*ads)->config.client_site_name); - SAFE_FREE((*ads)->schema.posix_uidnumber_attr); - SAFE_FREE((*ads)->schema.posix_gidnumber_attr); - SAFE_FREE((*ads)->schema.posix_shell_attr); - SAFE_FREE((*ads)->schema.posix_homedir_attr); - SAFE_FREE((*ads)->schema.posix_gecos_attr); - ZERO_STRUCTP(*ads); if ( is_mine ) diff --git a/source3/libads/ldap_schema.c b/source3/libads/ldap_schema.c index b4a512cbfe..5d91d98549 100644 --- a/source3/libads/ldap_schema.c +++ b/source3/libads/ldap_schema.c @@ -186,7 +186,10 @@ static ADS_STATUS ads_schema_path(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char **s * @return ADS_STATUS status of search (False if one or more attributes couldn't be * found in Active Directory) **/ -ADS_STATUS ads_check_posix_schema_mapping(ADS_STRUCT *ads, enum wb_posix_mapping map_type) +ADS_STATUS ads_check_posix_schema_mapping(TALLOC_CTX *mem_ctx, + ADS_STRUCT *ads, + enum wb_posix_mapping map_type, + struct posix_schema **s ) { TALLOC_CTX *ctx = NULL; ADS_STATUS status; @@ -194,6 +197,7 @@ ADS_STATUS ads_check_posix_schema_mapping(ADS_STRUCT *ads, enum wb_posix_mapping size_t num_names; char *schema_path = NULL; int i; + struct posix_schema *schema = NULL; const char *oids_sfu[] = { ADS_ATTR_SFU_UIDNUMBER_OID, ADS_ATTR_SFU_GIDNUMBER_OID, @@ -209,34 +213,15 @@ ADS_STATUS ads_check_posix_schema_mapping(ADS_STRUCT *ads, enum wb_posix_mapping DEBUG(10,("ads_check_posix_schema_mapping\n")); - switch (map_type) { - - case WB_POSIX_MAP_TEMPLATE: - case WB_POSIX_MAP_UNIXINFO: - DEBUG(10,("ads_check_posix_schema_mapping: nothing to do\n")); - return ADS_ERROR(LDAP_SUCCESS); - - case WB_POSIX_MAP_SFU: - case WB_POSIX_MAP_RFC2307: - break; - - default: - DEBUG(0,("ads_check_posix_schema_mapping: " - "unknown enum %d\n", map_type)); - return ADS_ERROR(LDAP_PARAM_ERROR); + if ( (ctx = talloc_init("ads_check_posix_schema_mapping")) == NULL ) { + return ADS_ERROR(LDAP_NO_MEMORY); } - ads->schema.posix_uidnumber_attr = NULL; - ads->schema.posix_gidnumber_attr = NULL; - ads->schema.posix_homedir_attr = NULL; - ads->schema.posix_shell_attr = NULL; - ads->schema.posix_gecos_attr = NULL; - - ctx = talloc_init("ads_check_posix_schema_mapping"); - if (ctx == NULL) { + if ( (schema = TALLOC_P(mem_ctx, struct posix_schema)) == NULL ) { + TALLOC_FREE( ctx ); return ADS_ERROR(LDAP_NO_MEMORY); } - + status = ads_schema_path(ads, ctx, &schema_path); if (!ADS_ERR_OK(status)) { DEBUG(3,("ads_check_posix_mapping: Unable to retrieve schema DN!\n")); @@ -257,10 +242,7 @@ ADS_STATUS ads_check_posix_schema_mapping(ADS_STRUCT *ads, enum wb_posix_mapping DEBUG(3,("ads_check_posix_schema_mapping: failed %s\n", ads_errstr(status))); goto done; - } - - DEBUG(10,("ads_check_posix_schema_mapping: query succeeded, identified: %s\n", - wb_posix_map_str(map_type))); + } for (i=0; ischema.posix_uidnumber_attr); - ads->schema.posix_uidnumber_attr = SMB_STRDUP(names_out[i]); + schema->posix_uidnumber_attr = talloc_strdup(schema, names_out[i]); + continue; } + if (strequal(ADS_ATTR_RFC2307_GIDNUMBER_OID, oids_out[i]) || strequal(ADS_ATTR_SFU_GIDNUMBER_OID, oids_out[i])) { - SAFE_FREE(ads->schema.posix_gidnumber_attr); - ads->schema.posix_gidnumber_attr = SMB_STRDUP(names_out[i]); + schema->posix_gidnumber_attr = talloc_strdup(schema, names_out[i]); + continue; } + if (strequal(ADS_ATTR_RFC2307_HOMEDIR_OID, oids_out[i]) || strequal(ADS_ATTR_SFU_HOMEDIR_OID, oids_out[i])) { - SAFE_FREE(ads->schema.posix_homedir_attr); - ads->schema.posix_homedir_attr = SMB_STRDUP(names_out[i]); + schema->posix_homedir_attr = talloc_strdup(schema, names_out[i]); + continue; } + if (strequal(ADS_ATTR_RFC2307_SHELL_OID, oids_out[i]) || strequal(ADS_ATTR_SFU_SHELL_OID, oids_out[i])) { - SAFE_FREE(ads->schema.posix_shell_attr); - ads->schema.posix_shell_attr = SMB_STRDUP(names_out[i]); + schema->posix_shell_attr = talloc_strdup(schema, names_out[i]); + continue; } + if (strequal(ADS_ATTR_RFC2307_GECOS_OID, oids_out[i]) || strequal(ADS_ATTR_SFU_GECOS_OID, oids_out[i])) { - SAFE_FREE(ads->schema.posix_gecos_attr); - ads->schema.posix_gecos_attr = SMB_STRDUP(names_out[i]); + schema->posix_gecos_attr = talloc_strdup(schema, names_out[i]); } } - if (!ads->schema.posix_uidnumber_attr || - !ads->schema.posix_gidnumber_attr || - !ads->schema.posix_homedir_attr || - !ads->schema.posix_shell_attr || - !ads->schema.posix_gecos_attr) { + if (!schema->posix_uidnumber_attr || + !schema->posix_gidnumber_attr || + !schema->posix_homedir_attr || + !schema->posix_shell_attr || + !schema->posix_gecos_attr) { status = ADS_ERROR(LDAP_NO_MEMORY); + TALLOC_FREE( schema ); goto done; } + + *s = schema; status = ADS_ERROR(LDAP_SUCCESS); - ads->schema.map_type = map_type; done: if (ctx) { talloc_destroy(ctx); -- cgit From 4b147350b8a8435320cf8fccc60724d7b8b776cc Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 24 Jan 2007 14:59:01 +0000 Subject: r21003: Display LDAP base in debug statement. Guenther (This used to be commit fb5830f87a16dbec16893348080bcdfc61e27ab0) --- source3/libads/ldap_utils.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap_utils.c b/source3/libads/ldap_utils.c index e6855674d1..af9e9af2b8 100644 --- a/source3/libads/ldap_utils.c +++ b/source3/libads/ldap_utils.c @@ -60,8 +60,8 @@ static ADS_STATUS ads_do_search_retry_internal(ADS_STRUCT *ads, const char *bind status = ads_do_search_all_args(ads, bp, scope, expr, attrs, args, res); } if (ADS_ERR_OK(status)) { - DEBUG(5,("Search for %s gave %d replies\n", - expr, ads_count_replies(ads, *res))); + DEBUG(5,("Search for %s in <%s> gave %d replies\n", + expr, bp, ads_count_replies(ads, *res))); SAFE_FREE(bp); return status; } -- cgit From 8751923635b93b0c53d7939e34fb8747e025ca59 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 25 Jan 2007 16:54:53 +0000 Subject: r21021: Fix memleak. Guenther (This used to be commit 4e622572eb7939c6aa8e99fd9595bf28836bd5a3) --- source3/libads/ldap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 4802f79d3e..d72cb4af26 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -301,6 +301,7 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads) goto again; } + SAFE_FREE(sitename); return status; } -- cgit From 594ab518a581f3728c82bdb9cf563e5fa449c0e1 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 29 Jan 2007 21:15:25 +0000 Subject: r21046: Backing out svn r20403 (Andrew's krb5 ticket cleanup as this is causing the WRONG_PASSWORD error in the SetUserInfo() call during net ads join). We are now back to always list RC4-HMAC first if supported by the krb5 libraries. (This used to be commit 4fb57bce87588ac4898588ea4988eadff3a7f435) --- source3/libads/sasl.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index d1699dbab7..7d1fd0d1a8 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -42,6 +42,7 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) if (!NT_STATUS_IS_OK(nt_status = ntlmssp_client_start(&ntlmssp_state))) { return ADS_ERROR_NT(nt_status); } + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SIGN; if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, ads->auth.user_name))) { return ADS_ERROR_NT(nt_status); @@ -282,6 +283,12 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) ADS_STATUS status; krb5_principal principal; krb5_context ctx = NULL; + krb5_enctype enc_types[] = { +#ifdef ENCTYPE_ARCFOUR_HMAC + ENCTYPE_ARCFOUR_HMAC, +#endif + ENCTYPE_DES_CBC_MD5, + ENCTYPE_NULL}; gss_OID_desc nt_principal = {10, CONST_DISCARD(char *, "\052\206\110\206\367\022\001\002\002\002")}; @@ -294,6 +301,10 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) if (!ADS_ERR_OK(status)) { return status; } + status = ADS_ERROR_KRB5(krb5_set_default_tgs_ktypes(ctx, enc_types)); + if (!ADS_ERR_OK(status)) { + return status; + } status = ADS_ERROR_KRB5(smb_krb5_parse_name(ctx, sname, &principal)); if (!ADS_ERR_OK(status)) { return status; -- cgit From 1898eaddb805e86d0c36bd289e7fa61d7bbd4810 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 1 Feb 2007 15:10:13 +0000 Subject: r21110: Fix kinit with Heimdal (Bug #4226). Guenther (This used to be commit ea38e1f8362d75e7ac058a7c4aa06f1ca92ec108) --- source3/libads/kerberos.c | 39 ++++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index d35b59f4cd..3d4b8cbcf8 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -75,7 +75,7 @@ int kerberos_kinit_password_ext(const char *principal, krb5_ccache cc = NULL; krb5_principal me; krb5_creds my_creds; - krb5_get_init_creds_opt opt; + krb5_get_init_creds_opt *opt = NULL; smb_krb5_addresses *addr = NULL; initialize_krb5_error_table(); @@ -96,47 +96,60 @@ int kerberos_kinit_password_ext(const char *principal, } if ((code = smb_krb5_parse_name(ctx, principal, &me))) { + krb5_cc_close(ctx, cc); krb5_free_context(ctx); return code; } - krb5_get_init_creds_opt_init(&opt); - krb5_get_init_creds_opt_set_renew_life(&opt, renewable_time); - krb5_get_init_creds_opt_set_forwardable(&opt, 1); - - if (request_pac) { + code = krb5_get_init_creds_opt_alloc(ctx, &opt); + if (code) { + krb5_cc_close(ctx, cc); + krb5_free_context(ctx); + return code; + } + + krb5_get_init_creds_opt_set_renew_life(opt, renewable_time); + krb5_get_init_creds_opt_set_forwardable(opt, True); + #ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PAC_REQUEST - code = krb5_get_init_creds_opt_set_pac_request(ctx, &opt, True); + if (request_pac) { + code = krb5_get_init_creds_opt_set_pac_request(ctx, opt, (krb5_boolean)request_pac); if (code) { + krb5_cc_close(ctx, cc); krb5_free_principal(ctx, me); krb5_free_context(ctx); return code; } -#endif } - +#endif if (add_netbios_addr) { code = smb_krb5_gen_netbios_krb5_address(&addr); if (code) { + krb5_cc_close(ctx, cc); krb5_free_principal(ctx, me); krb5_free_context(ctx); return code; } - krb5_get_init_creds_opt_set_address_list(&opt, addr->addrs); + krb5_get_init_creds_opt_set_address_list(opt, addr->addrs); } if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, CONST_DISCARD(char *,password), - kerb_prompter, NULL, 0, NULL, &opt))) + kerb_prompter, NULL, 0, NULL, opt))) { + krb5_get_init_creds_opt_free(opt); smb_krb5_free_addresses(ctx, addr); + krb5_cc_close(ctx, cc); krb5_free_principal(ctx, me); - krb5_free_context(ctx); + krb5_free_context(ctx); return code; } - + + krb5_get_init_creds_opt_free(opt); + if ((code = krb5_cc_initialize(ctx, cc, me))) { smb_krb5_free_addresses(ctx, addr); krb5_free_cred_contents(ctx, &my_creds); + krb5_cc_close(ctx, cc); krb5_free_principal(ctx, me); krb5_free_context(ctx); return code; -- cgit From aad88ee34f8831891a96da7e462214c6cf1a3b0d Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 8 Feb 2007 13:50:47 +0000 Subject: r21238: Fix tab indent in self-written krb5.confs. Guenther (This used to be commit 4df582fa1049afe96bbee7e8cab93cfa82208ba3) --- source3/libads/kerberos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 3d4b8cbcf8..92461bd9c1 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -617,7 +617,7 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do file_contents = talloc_asprintf(fname, "[libdefaults]\n\tdefault_realm = %s\n\n" "[realms]\n\t%s = {\n" - "\t\t%s\t}\n", + "\t%s\t}\n", realm_upper, realm_upper, kdc_ip_string); if (!file_contents) { -- cgit From 69cee2a3ec4f39aab83a8cbf55307df182bf3065 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 8 Feb 2007 17:02:39 +0000 Subject: r21240: Fix longstanding Bug #4009. For the winbind cached ADS LDAP connection handling (ads_cached_connection()) we were (incorrectly) assuming that the service ticket lifetime equaled the tgt lifetime. For setups where the service ticket just lives 10 minutes, we were leaving hundreds of LDAP connections in CLOSE_WAIT state, until we fail to service entirely with "Too many open files". Also sequence_number() in winbindd_ads.c needs to delete the cached LDAP connection after the ads_do_search_retry() has failed to submit the search request (although the bind succeeded (returning an expired service ticket that we cannot delete from the memory cred cache - this will get fixed later)). Guenther (This used to be commit 7e1a84b7226fb8dcd5d34c64a3478a6d886a9a91) --- source3/libads/kerberos.c | 6 +++++- source3/libads/ldap_utils.c | 4 ++-- source3/libads/sasl.c | 8 ++++++-- 3 files changed, 13 insertions(+), 5 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 92461bd9c1..8e8297b07e 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -110,6 +110,10 @@ int kerberos_kinit_password_ext(const char *principal, krb5_get_init_creds_opt_set_renew_life(opt, renewable_time); krb5_get_init_creds_opt_set_forwardable(opt, True); +#if 0 + /* insane testing */ + krb5_get_init_creds_opt_set_tkt_life(opt, 60); +#endif #ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PAC_REQUEST if (request_pac) { @@ -216,7 +220,7 @@ int ads_kinit_password(ADS_STRUCT *ads) } ret = kerberos_kinit_password_ext(s, ads->auth.password, ads->auth.time_offset, - &ads->auth.expire, NULL, NULL, False, False, ads->auth.renewable); + &ads->auth.tgt_expire, NULL, NULL, False, False, ads->auth.renewable); if (ret) { DEBUG(0,("kerberos_kinit_password %s failed: %s\n", diff --git a/source3/libads/ldap_utils.c b/source3/libads/ldap_utils.c index af9e9af2b8..1da51b3c5c 100644 --- a/source3/libads/ldap_utils.c +++ b/source3/libads/ldap_utils.c @@ -110,10 +110,10 @@ static ADS_STATUS ads_do_search_retry_internal(ADS_STRUCT *ads, const char *bind } SAFE_FREE(bp); - if (!ADS_ERR_OK(status)) + if (!ADS_ERR_OK(status)) { DEBUG(1,("ads reopen failed after error %s\n", ads_errstr(status))); - + } return status; } diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 7d1fd0d1a8..61fd54da1d 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -147,7 +147,8 @@ static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *princip DATA_BLOB session_key = data_blob(NULL, 0); int rc; - rc = spnego_gen_negTokenTarg(principal, ads->auth.time_offset, &blob, &session_key, 0); + rc = spnego_gen_negTokenTarg(principal, ads->auth.time_offset, &blob, &session_key, 0, + &ads->auth.tgs_expire); if (rc) { return ADS_ERROR_KRB5(rc); @@ -218,7 +219,7 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) #endif free(OIDs[i]); } - DEBUG(3,("ads_sasl_spnego_bind: got server principal name =%s\n", principal)); + DEBUG(3,("ads_sasl_spnego_bind: got server principal name = %s\n", principal)); #ifdef HAVE_KRB5 if (!(ads->auth.flags & ADS_AUTH_DISABLE_KERBEROS) && @@ -229,6 +230,9 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) return status; } + DEBUG(10,("ads_sasl_spnego_krb5_bind failed with: %s, " + "calling kinit\n", ads_errstr(status))); + status = ADS_ERROR_KRB5(ads_kinit_password(ads)); if (ADS_ERR_OK(status)) { -- cgit From 763a553046bfb6e28998adfb671c473485e9f5dc Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Sat, 10 Feb 2007 20:29:09 +0000 Subject: r21273: * Protect the sasl bind against a NULL principal string in the SPNEGO negTokenInit (This used to be commit fe70c224964bf15d626bfd4e0cc6d060e45bba87) --- source3/libads/sasl.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 61fd54da1d..812f3961f1 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -223,7 +223,35 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) #ifdef HAVE_KRB5 if (!(ads->auth.flags & ADS_AUTH_DISABLE_KERBEROS) && - got_kerberos_mechanism) { + got_kerberos_mechanism) + { + /* I've seen a child Windows 2000 domain not send + the principal name back in the first round of + the SASL bind reply. So we guess based on server + name and realm. --jerry */ + if ( !principal ) { + if ( ads->server.realm && ads->server.ldap_server ) { + char *server, *server_realm; + + server = SMB_STRDUP( ads->server.ldap_server ); + server_realm = SMB_STRDUP( ads->server.realm ); + + if ( !server || !server_realm ) + return ADS_ERROR(LDAP_NO_MEMORY); + + strlower_m( server ); + strupper_m( server_realm ); + asprintf( &principal, "ldap/%s@%s", server, server_realm ); + + SAFE_FREE( server ); + SAFE_FREE( server_realm ); + + if ( !principal ) + return ADS_ERROR(LDAP_NO_MEMORY); + } + + } + status = ads_sasl_spnego_krb5_bind(ads, principal); if (ADS_ERR_OK(status)) { SAFE_FREE(principal); -- cgit From 08726ffcd47eeb68eb7724e09d25322417517513 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 14 Feb 2007 20:52:23 +0000 Subject: r21349: Fix memleak in ads_upn_suffixes(). Guenther (This used to be commit 8462f323cf86f90b1bdf14a3953c5a4bda1b9533) --- source3/libads/ldap.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index d72cb4af26..949d167013 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2638,9 +2638,12 @@ ADS_STATUS ads_upn_suffixes(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char **suffixe config_context = ads_pull_string(ads, mem_ctx, res, "configurationNamingContext"); if (config_context == NULL) { + ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_MEMORY); } + ads_msgfree(ads, res); + base = talloc_asprintf(mem_ctx, "cn=Partitions,%s", config_context); if (base == NULL) { return ADS_ERROR(LDAP_NO_MEMORY); -- cgit From 5aa3b27949009bafe1e85d468b191f33c4c29293 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 15 Feb 2007 00:03:38 +0000 Subject: r21352: Let ads_upn_suffixes() return a pointer to an array of suffixes. Guenther (This used to be commit 7ad7847e5bbdd90fa6ae9ce91e5962f524ac2890) --- source3/libads/ldap.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 949d167013..dfc68fdc2b 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2620,10 +2620,10 @@ ADS_STATUS ads_site_dn_for_machine(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const c * @param ads connection to ads server * @param mem_ctx Pointer to talloc context * @param suffixes Pointer to an array of suffixes - * @param site_name Pointer to the number of suffixes + * @param num_suffixes Pointer to the number of suffixes * @return status of search **/ -ADS_STATUS ads_upn_suffixes(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char **suffixes, size_t *num_suffixes) +ADS_STATUS ads_upn_suffixes(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char ***suffixes, size_t *num_suffixes) { ADS_STATUS status; LDAPMessage *res; @@ -2658,8 +2658,8 @@ ADS_STATUS ads_upn_suffixes(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char **suffixe return ADS_ERROR(LDAP_NO_SUCH_OBJECT); } - suffixes = ads_pull_strings(ads, mem_ctx, res, "uPNSuffixes", num_suffixes); - if (suffixes == NULL) { + (*suffixes) = ads_pull_strings(ads, mem_ctx, res, "uPNSuffixes", num_suffixes); + if ((*suffixes) == NULL) { ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_MEMORY); } -- cgit From 3e946cbb85b387a943a834df172c09801971f7e8 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 27 Feb 2007 13:25:42 +0000 Subject: r21556: Remove superfluos return check in ads_keytab_verify_ticket(). Guenther (This used to be commit 020601ea0abeb15f2aef9da354fcf6d7d5459710) --- source3/libads/kerberos_verify.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index dc2f2a1e78..03e30a9ba3 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -88,7 +88,6 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut goto out; } - if (ret != KRB5_KT_END && ret != ENOENT ) { while (!auth_ok && (krb5_kt_next_entry(context, keytab, &kt_entry, &kt_cursor) == 0)) { ret = smb_krb5_unparse_name(context, kt_entry.principal, &entry_princ_s); if (ret) { @@ -146,7 +145,6 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut ZERO_STRUCT(kt_entry); } krb5_kt_end_seq_get(context, keytab, &kt_cursor); - } ZERO_STRUCT(kt_cursor); -- cgit From 59e8bd617b921166edc86b01e522f5ef81fc06f7 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 27 Feb 2007 13:27:31 +0000 Subject: r21557: indent only fix. No code change. Guenther (This used to be commit 8ff0903a17cfd8c09b73ef637484a72719e82071) --- source3/libads/kerberos_verify.c | 98 ++++++++++++++++++++-------------------- 1 file changed, 49 insertions(+), 49 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 03e30a9ba3..72b6ac34e9 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -88,63 +88,63 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut goto out; } - while (!auth_ok && (krb5_kt_next_entry(context, keytab, &kt_entry, &kt_cursor) == 0)) { - ret = smb_krb5_unparse_name(context, kt_entry.principal, &entry_princ_s); - if (ret) { - DEBUG(1, ("ads_keytab_verify_ticket: smb_krb5_unparse_name failed (%s)\n", - error_message(ret))); - goto out; - } + while (!auth_ok && (krb5_kt_next_entry(context, keytab, &kt_entry, &kt_cursor) == 0)) { + ret = smb_krb5_unparse_name(context, kt_entry.principal, &entry_princ_s); + if (ret) { + DEBUG(1, ("ads_keytab_verify_ticket: smb_krb5_unparse_name failed (%s)\n", + error_message(ret))); + goto out; + } - for (i = 0; i < sizeof(valid_princ_formats) / sizeof(valid_princ_formats[0]); i++) { - if (strequal(entry_princ_s, valid_princ_formats[i])) { - number_matched_principals++; - p_packet->length = ticket->length; - p_packet->data = (char *)ticket->data; - *pp_tkt = NULL; - - ret = krb5_rd_req_return_keyblock_from_keytab(context, &auth_context, p_packet, - kt_entry.principal, keytab, - NULL, pp_tkt, keyblock); - - if (ret) { - DEBUG(10,("ads_keytab_verify_ticket: " - "krb5_rd_req_return_keyblock_from_keytab(%s) failed: %s\n", - entry_princ_s, error_message(ret))); - - /* workaround for MIT: - * as krb5_ktfile_get_entry will - * explicitly close the - * krb5_keytab as soon as - * krb5_rd_req has sucessfully - * decrypted the ticket but the - * ticket is not valid yet (due - * to clockskew) there is no - * point in querying more - * keytab entries - Guenther */ + for (i = 0; i < sizeof(valid_princ_formats) / sizeof(valid_princ_formats[0]); i++) { + if (strequal(entry_princ_s, valid_princ_formats[i])) { + number_matched_principals++; + p_packet->length = ticket->length; + p_packet->data = (char *)ticket->data; + *pp_tkt = NULL; + + ret = krb5_rd_req_return_keyblock_from_keytab(context, &auth_context, p_packet, + kt_entry.principal, keytab, + NULL, pp_tkt, keyblock); + + if (ret) { + DEBUG(10,("ads_keytab_verify_ticket: " + "krb5_rd_req_return_keyblock_from_keytab(%s) failed: %s\n", + entry_princ_s, error_message(ret))); + + /* workaround for MIT: + * as krb5_ktfile_get_entry will + * explicitly close the + * krb5_keytab as soon as + * krb5_rd_req has sucessfully + * decrypted the ticket but the + * ticket is not valid yet (due + * to clockskew) there is no + * point in querying more + * keytab entries - Guenther */ - if (ret == KRB5KRB_AP_ERR_TKT_NYV || - ret == KRB5KRB_AP_ERR_TKT_EXPIRED) { - break; - } - } else { - DEBUG(3,("ads_keytab_verify_ticket: " - "krb5_rd_req_return_keyblock_from_keytab succeeded for principal %s\n", - entry_princ_s)); - auth_ok = True; + if (ret == KRB5KRB_AP_ERR_TKT_NYV || + ret == KRB5KRB_AP_ERR_TKT_EXPIRED) { break; } + } else { + DEBUG(3,("ads_keytab_verify_ticket: " + "krb5_rd_req_return_keyblock_from_keytab succeeded for principal %s\n", + entry_princ_s)); + auth_ok = True; + break; } } + } - /* Free the name we parsed. */ - SAFE_FREE(entry_princ_s); + /* Free the name we parsed. */ + SAFE_FREE(entry_princ_s); - /* Free the entry we just read. */ - smb_krb5_kt_free_entry(context, &kt_entry); - ZERO_STRUCT(kt_entry); - } - krb5_kt_end_seq_get(context, keytab, &kt_cursor); + /* Free the entry we just read. */ + smb_krb5_kt_free_entry(context, &kt_entry); + ZERO_STRUCT(kt_entry); + } + krb5_kt_end_seq_get(context, keytab, &kt_cursor); ZERO_STRUCT(kt_cursor); -- cgit From 4e00351fd426e6c016fd433887f62deda632f0aa Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 27 Feb 2007 13:31:42 +0000 Subject: r21558: Safe more indent, again no code changes. Guenther (This used to be commit 7b18a4730d61c04867fc11df8980943d422589d8) --- source3/libads/kerberos_verify.c | 74 ++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 37 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 72b6ac34e9..2c114b1240 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -96,44 +96,44 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut goto out; } - for (i = 0; i < sizeof(valid_princ_formats) / sizeof(valid_princ_formats[0]); i++) { - if (strequal(entry_princ_s, valid_princ_formats[i])) { - number_matched_principals++; - p_packet->length = ticket->length; - p_packet->data = (char *)ticket->data; - *pp_tkt = NULL; - - ret = krb5_rd_req_return_keyblock_from_keytab(context, &auth_context, p_packet, - kt_entry.principal, keytab, - NULL, pp_tkt, keyblock); - - if (ret) { - DEBUG(10,("ads_keytab_verify_ticket: " - "krb5_rd_req_return_keyblock_from_keytab(%s) failed: %s\n", - entry_princ_s, error_message(ret))); - - /* workaround for MIT: - * as krb5_ktfile_get_entry will - * explicitly close the - * krb5_keytab as soon as - * krb5_rd_req has sucessfully - * decrypted the ticket but the - * ticket is not valid yet (due - * to clockskew) there is no - * point in querying more - * keytab entries - Guenther */ - - if (ret == KRB5KRB_AP_ERR_TKT_NYV || - ret == KRB5KRB_AP_ERR_TKT_EXPIRED) { - break; - } - } else { - DEBUG(3,("ads_keytab_verify_ticket: " - "krb5_rd_req_return_keyblock_from_keytab succeeded for principal %s\n", - entry_princ_s)); - auth_ok = True; + for (i = 0; i < ARRAY_SIZE(valid_princ_formats); i++) { + + if (!strequal(entry_princ_s, valid_princ_formats[i])) { + continue; + } + + number_matched_principals++; + p_packet->length = ticket->length; + p_packet->data = (char *)ticket->data; + *pp_tkt = NULL; + + ret = krb5_rd_req_return_keyblock_from_keytab(context, &auth_context, p_packet, + kt_entry.principal, keytab, + NULL, pp_tkt, keyblock); + + if (ret) { + DEBUG(10,("ads_keytab_verify_ticket: " + "krb5_rd_req_return_keyblock_from_keytab(%s) failed: %s\n", + entry_princ_s, error_message(ret))); + + /* workaround for MIT: + * as krb5_ktfile_get_entry will explicitly + * close the krb5_keytab as soon as krb5_rd_req + * has sucessfully decrypted the ticket but the + * ticket is not valid yet (due to clockskew) + * there is no point in querying more keytab + * entries - Guenther */ + + if (ret == KRB5KRB_AP_ERR_TKT_NYV || + ret == KRB5KRB_AP_ERR_TKT_EXPIRED) { break; } + } else { + DEBUG(3,("ads_keytab_verify_ticket: " + "krb5_rd_req_return_keyblock_from_keytab succeeded for principal %s\n", + entry_princ_s)); + auth_ok = True; + break; } } @@ -150,7 +150,7 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut out: - for (i = 0; i < sizeof(valid_princ_formats) / sizeof(valid_princ_formats[0]); i++) { + for (i = 0; i < ARRAY_SIZE(valid_princ_formats); i++) { SAFE_FREE(valid_princ_formats[i]); } -- cgit From 81e4a28718632c1e5173ecb8b16db43cde439254 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 27 Feb 2007 14:24:49 +0000 Subject: r21561: It makes absolutely no sense to call krb5_kt_resolve() two times directly after another. Guenther (This used to be commit 76ba11d7770bac7c6db2eb1640139bbe270d82c3) --- source3/libads/kerberos_keytab.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c index 4b640151d3..ba1a916567 100644 --- a/source3/libads/kerberos_keytab.c +++ b/source3/libads/kerberos_keytab.c @@ -408,12 +408,7 @@ int ads_keytab_flush(ADS_STRUCT *ads) DEBUG(3,("ads_keytab_flush: Using default keytab: %s\n", (char *) &keytab_name)); ret = krb5_kt_resolve(context, (char *) &keytab_name, &keytab); if (ret) { - DEBUG(1,("ads_keytab_flush: krb5_kt_default failed (%s)\n", error_message(ret))); - goto out; - } - ret = krb5_kt_resolve(context, (char *) &keytab_name, &keytab); - if (ret) { - DEBUG(1,("ads_keytab_flush: krb5_kt_default failed (%s)\n", error_message(ret))); + DEBUG(1,("ads_keytab_flush: krb5_kt_resolve failed (%s)\n", error_message(ret))); goto out; } -- cgit From e9e6af59510242fbc78fd2100026d8dc79f18773 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Thu, 1 Mar 2007 00:49:28 +0000 Subject: r21606: Implement escaping function for ldap RDN values Fix escaping of DN components and filters around the code Add some notes to commandline help messages about how to pass DNs revert jra's "concistency" commit to nsswitch/winbindd_ads.c, as it was incorrect. The 2 functions use DNs in different ways. - lookup_usergroups_member() uses the DN in a search filter, and must use the filter escaping function to escape it Escaping filters that include escaped DNs ("\," becomes "\5c,") is the correct way to do it (tested against W2k3). - lookup_usergroups_memberof() instead uses the DN ultimately as a base dn. Both functions do NOT need any DN escaping function as DNs can't be reliably escaped when in a string form, intead each single RDN value must be escaped separately. DNs coming from other ldap calls (like ads_get_dn()), do not need escaping as they come already escaped on the wire and passed as is by the ldap libraries DN filtering has been tested. For example now it is possible to do something like: 'net ads add user joe#5' as now the '#' character is correctly escaped when building the DN, previously such a call failed with Invalid DN Syntax. Simo. (This used to be commit 5b4838f62ab1a92bfe02626ef40d7f94c2598322) --- source3/libads/ldap.c | 10 ++++++++-- source3/libads/ldap_user.c | 12 ++++++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index dfc68fdc2b..e9d8bf6bbf 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1635,6 +1635,7 @@ ADS_STATUS ads_create_machine_acct(ADS_STRUCT *ads, const char *machine_name, char *samAccountName, *controlstr; TALLOC_CTX *ctx; ADS_MODLIST mods; + char *machine_escaped; char *new_dn; const char *objectClass[] = {"top", "person", "organizationalPerson", "user", "computer", NULL}; @@ -1647,8 +1648,13 @@ ADS_STATUS ads_create_machine_acct(ADS_STRUCT *ads, const char *machine_name, return ADS_ERROR(LDAP_NO_MEMORY); ret = ADS_ERROR(LDAP_NO_MEMORY); - - new_dn = talloc_asprintf(ctx, "cn=%s,%s", machine_name, org_unit); + + machine_escaped = escape_rdn_val_string_alloc(machine_name); + if (!machine_escaped) { + goto done; + } + + new_dn = talloc_asprintf(ctx, "cn=%s,%s", machine_escaped, org_unit); samAccountName = talloc_asprintf(ctx, "%s$", machine_name); if ( !new_dn || !samAccountName ) { diff --git a/source3/libads/ldap_user.c b/source3/libads/ldap_user.c index 66d94d29d3..afbbc0b421 100644 --- a/source3/libads/ldap_user.c +++ b/source3/libads/ldap_user.c @@ -50,6 +50,7 @@ ADS_STATUS ads_add_user_acct(ADS_STRUCT *ads, const char *user, ADS_MODLIST mods; ADS_STATUS status; const char *upn, *new_dn, *name, *controlstr; + char *name_escaped = NULL; const char *objectClass[] = {"top", "person", "organizationalPerson", "user", NULL}; @@ -63,7 +64,9 @@ ADS_STATUS ads_add_user_acct(ADS_STRUCT *ads, const char *user, if (!(upn = talloc_asprintf(ctx, "%s@%s", user, ads->config.realm))) goto done; - if (!(new_dn = talloc_asprintf(ctx, "cn=%s,%s,%s", name, container, + if (!(name_escaped = escape_rdn_val_string_alloc(name))) + goto done; + if (!(new_dn = talloc_asprintf(ctx, "cn=%s,%s,%s", name_escaped, container, ads->config.bind_path))) goto done; if (!(controlstr = talloc_asprintf(ctx, "%u", (UF_NORMAL_ACCOUNT | UF_ACCOUNTDISABLE)))) @@ -81,6 +84,7 @@ ADS_STATUS ads_add_user_acct(ADS_STRUCT *ads, const char *user, status = ads_gen_add(ads, new_dn, mods); done: + SAFE_FREE(name_escaped); talloc_destroy(ctx); return status; } @@ -92,6 +96,7 @@ ADS_STATUS ads_add_group_acct(ADS_STRUCT *ads, const char *group, ADS_MODLIST mods; ADS_STATUS status; char *new_dn; + char *name_escaped = NULL; const char *objectClass[] = {"top", "group", NULL}; if (!(ctx = talloc_init("ads_add_group_acct"))) @@ -99,7 +104,9 @@ ADS_STATUS ads_add_group_acct(ADS_STRUCT *ads, const char *group, status = ADS_ERROR(LDAP_NO_MEMORY); - if (!(new_dn = talloc_asprintf(ctx, "cn=%s,%s,%s", group, container, + if (!(name_escaped = escape_rdn_val_string_alloc(group))) + goto done; + if (!(new_dn = talloc_asprintf(ctx, "cn=%s,%s,%s", name_escaped, container, ads->config.bind_path))) goto done; if (!(mods = ads_init_mods(ctx))) @@ -114,6 +121,7 @@ ADS_STATUS ads_add_group_acct(ADS_STRUCT *ads, const char *group, status = ads_gen_add(ads, new_dn, mods); done: + SAFE_FREE(name_escaped); talloc_destroy(ctx); return status; } -- cgit From fae01b48994fd3168fd921af68dab1b4003adc49 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 1 Mar 2007 01:17:36 +0000 Subject: r21608: Fix a couple of memleaks in error code paths before Coverity finds them :-) Jeremy. (This used to be commit cbe725f1b09f3d0edbdf823e0862edf21e16d336) --- source3/libads/ldap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index e9d8bf6bbf..1d08a01a26 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1635,7 +1635,7 @@ ADS_STATUS ads_create_machine_acct(ADS_STRUCT *ads, const char *machine_name, char *samAccountName, *controlstr; TALLOC_CTX *ctx; ADS_MODLIST mods; - char *machine_escaped; + char *machine_escaped = NULL; char *new_dn; const char *objectClass[] = {"top", "person", "organizationalPerson", "user", "computer", NULL}; @@ -1681,6 +1681,7 @@ ADS_STATUS ads_create_machine_acct(ADS_STRUCT *ads, const char *machine_name, ret = ads_gen_add(ads, new_dn, mods); done: + SAFE_FREE(machine_escaped); ads_msgfree(ads, res); talloc_destroy(ctx); -- cgit From aab1dd4ddbe45c625a6e4502cecd20da5762739b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 7 Mar 2007 22:29:21 +0000 Subject: r21755: Memory leak fixes from Zack Kirsch . Jeremy. (This used to be commit 02d08ca0be8c374e30c3c0e665853fa9e57f043a) --- source3/libads/cldap.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/cldap.c b/source3/libads/cldap.c index 72018c620d..3cb98c59c5 100644 --- a/source3/libads/cldap.c +++ b/source3/libads/cldap.c @@ -187,8 +187,10 @@ static int recv_cldap_netlogon(int sock, struct cldap_netlogon_reply *reply) { int ret; ASN1_DATA data; - DATA_BLOB blob; - DATA_BLOB os1, os2, os3; + DATA_BLOB blob = data_blob(NULL, 0); + DATA_BLOB os1 = data_blob(NULL, 0); + DATA_BLOB os2 = data_blob(NULL, 0); + DATA_BLOB os3 = data_blob(NULL, 0); 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); @@ -238,6 +240,9 @@ static int recv_cldap_netlogon(int sock, struct cldap_netlogon_reply *reply) 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; -- cgit From 3adeb4274250ec4420d9d874b07d8e688a354402 Mon Sep 17 00:00:00 2001 From: James Peach Date: Fri, 9 Mar 2007 18:51:48 +0000 Subject: r21778: Wrap calls to krb5_get_init_creds_opt_free to handle the different calling convention in the latest MIT changes. Apparantly Heimdal is also changing to this calling convention. (This used to be commit c29c69d2df377fabb88a78e6f5237de106d5c2c5) --- source3/libads/kerberos.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 8e8297b07e..1c0e85dd55 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -140,7 +140,7 @@ int kerberos_kinit_password_ext(const char *principal, if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, CONST_DISCARD(char *,password), kerb_prompter, NULL, 0, NULL, opt))) { - krb5_get_init_creds_opt_free(opt); + smb_krb5_get_init_creds_opt_free(ctx, opt); smb_krb5_free_addresses(ctx, addr); krb5_cc_close(ctx, cc); krb5_free_principal(ctx, me); @@ -148,7 +148,7 @@ int kerberos_kinit_password_ext(const char *principal, return code; } - krb5_get_init_creds_opt_free(opt); + smb_krb5_get_init_creds_opt_free(ctx, opt); if ((code = krb5_cc_initialize(ctx, cc, me))) { smb_krb5_free_addresses(ctx, addr); -- cgit From 98e58694eed08f24e9d243445655aa0105b98ecc Mon Sep 17 00:00:00 2001 From: James Peach Date: Fri, 9 Mar 2007 19:28:35 +0000 Subject: r21779: I missd a call to krb5_get_init_creds_opt_alloc in r21778. (This used to be commit 4f6c2826aa1ac240b02122a40fe9a1ccabaaaf27) --- source3/libads/kerberos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 1c0e85dd55..b6627075b0 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -101,7 +101,7 @@ int kerberos_kinit_password_ext(const char *principal, return code; } - code = krb5_get_init_creds_opt_alloc(ctx, &opt); + code = smb_krb5_get_init_creds_opt_alloc(ctx, &opt); if (code) { krb5_cc_close(ctx, cc); krb5_free_context(ctx); -- cgit From 0e702698f9a7cf0e528f073bae65371ed58e5496 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 13 Mar 2007 16:04:17 +0000 Subject: r21822: Adding experimental krb5 lib locator plugin. This is a starting point and may get changed. Basically we need follow the exact same path to detect (K)DCs like other Samba tools/winbind do. In particular with regard to the server affinity cache and the site-awarness for DNS SRV lookups. To compile just call "make bin/smb_krb5_locator.so", copy to /usr/lib/plugin/krb5/ (Heimdal HEAD) or /usr/lib/krb5/plugins/libkrb5/ (MIT) and you should immediately be able to kinit to your AD domain without having your REALM with kdc or kpasswd directives defined in /etc/krb5.conf at all. Tested with todays Heimdal HEAD and MIT krb5 1.5. Guenther (This used to be commit 34ae610bd5b9fd1210f16beac07a1c5984144ca7) --- source3/libads/smb_krb5_locator.c | 384 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 384 insertions(+) create mode 100644 source3/libads/smb_krb5_locator.c (limited to 'source3/libads') diff --git a/source3/libads/smb_krb5_locator.c b/source3/libads/smb_krb5_locator.c new file mode 100644 index 0000000000..9861511714 --- /dev/null +++ b/source3/libads/smb_krb5_locator.c @@ -0,0 +1,384 @@ +/* + Unix SMB/CIFS implementation. + kerberos locator plugin + Copyright (C) Guenther Deschner 2007 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +#if defined(HAVE_KRB5) && defined(HAVE_KRB5_LOCATE_PLUGIN_H) + +#include + +static const char *get_service_from_locate_service_type(enum locate_service_type svc) +{ + switch (svc) { + case locate_service_kdc: + case locate_service_master_kdc: + return "88"; + case locate_service_kadmin: + case locate_service_krb524: + /* not supported */ + return NULL; + case locate_service_kpasswd: + return "464"; + default: + break; + } + return NULL; + +} + +static const char *locate_service_type_name(enum locate_service_type svc) +{ + switch (svc) { + case locate_service_kdc: + return "locate_service_kdc"; + case locate_service_master_kdc: + return "locate_service_master_kdc"; + case locate_service_kadmin: + return "locate_service_kadmin"; + case locate_service_krb524: + return "locate_service_krb524"; + case locate_service_kpasswd: + return "locate_service_kpasswd"; + default: + break; + } + return NULL; +} + +static const char *socktype_name(int socktype) +{ + switch (socktype) { + case SOCK_STREAM: + return "SOCK_STREAM"; + case SOCK_DGRAM: + return "SOCK_DGRAM"; + default: + break; + } + return "unknown"; +} + +static const char *family_name(int family) +{ + switch (family) { + case AF_UNSPEC: + return "AF_UNSPEC"; + case AF_INET: + return "AF_INET"; + case AF_INET6: + return "AF_INET6"; + default: + break; + } + return "unknown"; +} + +/** + * Check input parameters, return KRB5_PLUGIN_NO_HANDLE for unsupported ones + * + * @param svc + * @param realm string + * @param socktype integer + * @param family integer + * + * @return integer. + */ + +static int smb_krb5_locator_lookup_sanity_check(enum locate_service_type svc, + const char *realm, + int socktype, + int family) +{ + if (!realm || strlen(realm) == 0) { + return EINVAL; + } + + switch (svc) { + case locate_service_kdc: + case locate_service_master_kdc: + case locate_service_kpasswd: + break; + case locate_service_kadmin: + case locate_service_krb524: +#ifdef KRB5_PLUGIN_NO_HANDLE + return KRB5_PLUGIN_NO_HANDLE; +#else + return KRB5_KDC_UNREACH; /* Heimdal */ +#endif + default: + return EINVAL; + } + + switch (family) { + case AF_UNSPEC: + case AF_INET: + break; + case AF_INET6: /* not yet */ +#ifdef KRB5_PLUGIN_NO_HANDLE + return KRB5_PLUGIN_NO_HANDLE; +#else + return KRB5_KDC_UNREACH; /* Heimdal */ +#endif + default: + return EINVAL; + } + + switch (socktype) { + case SOCK_STREAM: + case SOCK_DGRAM: + case 0: /* Heimdal uses that */ + break; + default: + return EINVAL; + } + + return 0; +} + +/** + * Try to get addrinfo for a given host and call the krb5 callback + * + * @param name string + * @param service string + * @param in struct addrinfo hint + * @param cbfunc krb5 callback function + * @param cbdata void pointer cbdata + * + * @return krb5_error_code. + */ + +static krb5_error_code smb_krb5_locator_call_cbfunc(const char *name, + const char *service, + struct addrinfo *in, + int (*cbfunc)(void *, int, struct sockaddr *), + void *cbdata) +{ + struct addrinfo *out; + int ret; + int count = 3; + + while (count) { + + ret = getaddrinfo(name, service, in, &out); + if (ret == 0) { + break; + } + + if (ret == EAI_AGAIN) { + count--; + continue; + } + + DEBUG(10,("smb_krb5_locator_lookup: got ret: %s (%d)\n", + gai_strerror(ret), ret)); +#ifdef KRB5_PLUGIN_NO_HANDLE + return KRB5_PLUGIN_NO_HANDLE; +#else + return KRB5_KDC_UNREACH; /* Heimdal */ +#endif + } + + ret = cbfunc(cbdata, out->ai_socktype, out->ai_addr); + if (ret) { + DEBUG(10,("smb_krb5_locator_lookup: failed to call callback: %s (%d)\n", + error_message(ret), ret)); + } + + freeaddrinfo(out); + + return ret; +} + +/** + * PUBLIC INTERFACE: locate init + * + * @param context krb5_context + * @param privata_data pointer to private data pointer + * + * @return krb5_error_code. + */ + +krb5_error_code smb_krb5_locator_init(krb5_context context, + void **private_data) +{ + setup_logging("smb_krb5_locator", True); + load_case_tables(); + lp_load(dyn_CONFIGFILE,True,False,False,True); + + DEBUG(10,("smb_krb5_locator_init: called\n")); + + return 0; +} + +/** + * PUBLIC INTERFACE: close locate + * + * @param private_data pointer to private data + * + * @return void. + */ + +void smb_krb5_locator_close(void *private_data) +{ + DEBUG(10,("smb_krb5_locator_close: called\n")); + + gfree_all(); +} + +/** + * PUBLIC INTERFACE: locate lookup + * + * @param private_data pointer to private data + * @param svc enum locate_service_type. + * @param realm string + * @param socktype integer + * @param family integer + * @param cbfunc callback function to send back entries + * @param cbdata void pointer to cbdata + * + * @return krb5_error_code. + */ + +krb5_error_code smb_krb5_locator_lookup(void *private_data, + enum locate_service_type svc, + const char *realm, + int socktype, + int family, + int (*cbfunc)(void *, int, struct sockaddr *), + void *cbdata) +{ + NTSTATUS status; + krb5_error_code ret; + char *sitename = NULL; + struct ip_service *ip_list; + int count = 0; + struct addrinfo aihints; + char *saf_name = NULL; + int i; + + DEBUG(10,("smb_krb5_locator_lookup: called for\n")); + DEBUGADD(10,("\tsvc: %s (%d), realm: %s\n", + locate_service_type_name(svc), svc, realm)); + DEBUGADD(10,("\tsocktype: %s (%d), family: %s (%d)\n", + socktype_name(socktype), socktype, + family_name(family), family)); + + ret = smb_krb5_locator_lookup_sanity_check(svc, realm, socktype, family); + if (ret) { + DEBUG(10,("smb_krb5_locator_lookup: returning ret: %s (%d)\n", + error_message(ret), ret)); + return ret; + } + + /* first try to fetch from SAF cache */ + + saf_name = saf_fetch(realm); + if (!saf_name || strlen(saf_name) == 0) { + DEBUG(10,("smb_krb5_locator_lookup: no SAF name stored for %s\n", + realm)); + goto find_kdc; + } + + DEBUG(10,("smb_krb5_locator_lookup: got %s for %s from SAF cache\n", + saf_name, realm)); + + ZERO_STRUCT(aihints); + + aihints.ai_family = family; + aihints.ai_socktype = socktype; + + ret = smb_krb5_locator_call_cbfunc(saf_name, + get_service_from_locate_service_type(svc), + &aihints, + cbfunc, cbdata); + if (ret) { + return ret; + } + + return 0; + + find_kdc: + + /* now try to find via site-aware DNS SRV query */ + + sitename = sitename_fetch(realm); + status = get_kdc_list(realm, sitename, &ip_list, &count); + + /* if we didn't found any KDCs on our site go to the main list */ + + if (NT_STATUS_IS_OK(status) && sitename && (count == 0)) { + ip_list = NULL; + SAFE_FREE(sitename); + status = get_kdc_list(realm, NULL, &ip_list, &count); + } + + SAFE_FREE(sitename); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10,("smb_krb5_locator_lookup: got %s (%s)\n", + nt_errstr(status), + error_message(nt_status_to_krb5(status)))); +#ifdef KRB5_PLUGIN_NO_HANDLE + return KRB5_PLUGIN_NO_HANDLE; +#else + return KRB5_KDC_UNREACH; /* Heimdal */ +#endif + } + + for (i=0; i Date: Tue, 13 Mar 2007 16:13:24 +0000 Subject: r21823: Let secrets_store_machine_password() also store the account name. Not used yet, the next step will be a secrets_fetch_machine_account() function that also pulls the account name to be used in the appropriate places. Volker (This used to be commit f94e5af72e282f70ca5454cdf3aed510b747eb93) --- source3/libads/util.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/util.c b/source3/libads/util.c index eb6dccb3af..669ed7d141 100644 --- a/source3/libads/util.c +++ b/source3/libads/util.c @@ -42,7 +42,9 @@ ADS_STATUS ads_change_trust_account_password(ADS_STRUCT *ads, char *host_princip goto failed; } - if (!secrets_store_machine_password(new_password, lp_workgroup(), sec_channel_type)) { + if (!secrets_store_machine_password(new_password, global_myname(), + lp_workgroup(), + sec_channel_type)) { DEBUG(1,("Failed to save machine password\n")); ret = ADS_ERROR_SYSTEM(EACCES); goto failed; -- cgit From f56da0890f645c4cecac7c60f67573e1f609fd4f Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 13 Mar 2007 20:53:38 +0000 Subject: r21831: Back out r21823 for a while, this is going into a bzr tree first. Volker (This used to be commit fd0ee6722ddfcb64b5cc9c699375524ae3d8709b) --- source3/libads/util.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/util.c b/source3/libads/util.c index 669ed7d141..eb6dccb3af 100644 --- a/source3/libads/util.c +++ b/source3/libads/util.c @@ -42,9 +42,7 @@ ADS_STATUS ads_change_trust_account_password(ADS_STRUCT *ads, char *host_princip goto failed; } - if (!secrets_store_machine_password(new_password, global_myname(), - lp_workgroup(), - sec_channel_type)) { + if (!secrets_store_machine_password(new_password, lp_workgroup(), sec_channel_type)) { DEBUG(1,("Failed to save machine password\n")); ret = ADS_ERROR_SYSTEM(EACCES); goto failed; -- cgit From edccfc91928c323f18febb7b90e41e0ddbfd8c7c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 15 Mar 2007 19:18:18 +0000 Subject: r21845: Refactor the sessionsetupX code a little to allow us to return a NT_STATUS_TIME_DIFFERENCE_AT_DC error to a client when there's clock skew. Will help people debug this. Prepare us for being able to return the correct sessionsetupX "NT_STATUS_MORE_PROCESSING_REQUIRED" error with associated krb5 clock skew error to allow clients to re-sync time with us when we're eventually able to be a KDC. Jeremy. (This used to be commit c426340fc79a6b446033433b8de599130adffe28) --- source3/libads/kerberos_verify.c | 103 +++++++++++++++++++++++++++------------ source3/libads/krb5_errs.c | 2 + 2 files changed, 74 insertions(+), 31 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 2c114b1240..0ec03ef4bf 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -7,6 +7,7 @@ Copyright (C) Guenther Deschner 2003, 2005 Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003 Copyright (C) Andrew Bartlett 2004-2005 + Copyright (C) Jeremy Allison 2007 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -37,9 +38,12 @@ const krb5_data *krb5_princ_component(krb5_context, krb5_principal, int ); ads_keytab_add_entry function for details. ***********************************************************************************/ -static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context auth_context, - const DATA_BLOB *ticket, krb5_data *p_packet, krb5_ticket **pp_tkt, - krb5_keyblock **keyblock) +static BOOL ads_keytab_verify_ticket(krb5_context context, + krb5_auth_context auth_context, + const DATA_BLOB *ticket, + krb5_ticket **pp_tkt, + krb5_keyblock **keyblock, + krb5_error_code *perr) { krb5_error_code ret = 0; BOOL auth_ok = False; @@ -51,6 +55,11 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut fstring my_name, my_fqdn; int i; int number_matched_principals = 0; + krb5_data packet; + + *pp_tkt = NULL; + *keyblock = NULL; + *perr = 0; /* Generate the list of principal names which we expect * clients might want to use for authenticating to the file @@ -103,11 +112,11 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut } number_matched_principals++; - p_packet->length = ticket->length; - p_packet->data = (char *)ticket->data; + packet.length = ticket->length; + packet.data = (char *)ticket->data; *pp_tkt = NULL; - ret = krb5_rd_req_return_keyblock_from_keytab(context, &auth_context, p_packet, + ret = krb5_rd_req_return_keyblock_from_keytab(context, &auth_context, &packet, kt_entry.principal, keytab, NULL, pp_tkt, keyblock); @@ -125,7 +134,8 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut * entries - Guenther */ if (ret == KRB5KRB_AP_ERR_TKT_NYV || - ret == KRB5KRB_AP_ERR_TKT_EXPIRED) { + ret == KRB5KRB_AP_ERR_TKT_EXPIRED || + ret == KRB5KRB_AP_ERR_SKEW) { break; } } else { @@ -184,6 +194,7 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut if (keytab) { krb5_kt_close(context, keytab); } + *perr = ret; return auth_ok; } @@ -191,32 +202,40 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut Try to verify a ticket using the secrets.tdb. ***********************************************************************************/ -static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context auth_context, - krb5_principal host_princ, - const DATA_BLOB *ticket, krb5_data *p_packet, krb5_ticket **pp_tkt, - krb5_keyblock **keyblock) +static krb5_error_code ads_secrets_verify_ticket(krb5_context context, + krb5_auth_context auth_context, + krb5_principal host_princ, + const DATA_BLOB *ticket, + krb5_ticket **pp_tkt, + krb5_keyblock **keyblock, + krb5_error_code *perr) { krb5_error_code ret = 0; BOOL auth_ok = False; char *password_s = NULL; krb5_data password; krb5_enctype enctypes[4] = { ENCTYPE_DES_CBC_CRC, ENCTYPE_DES_CBC_MD5, 0, 0 }; + krb5_data packet; int i; + *pp_tkt = NULL; + *keyblock = NULL; + *perr = 0; + #if defined(ENCTYPE_ARCFOUR_HMAC) enctypes[2] = ENCTYPE_ARCFOUR_HMAC; #endif - ZERO_STRUCTP(keyblock); - if (!secrets_init()) { DEBUG(1,("ads_secrets_verify_ticket: secrets_init failed\n")); + *perr = KRB5_CONFIG_CANTOPEN; return False; } password_s = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL); if (!password_s) { DEBUG(1,("ads_secrets_verify_ticket: failed to fetch machine password\n")); + *perr = KRB5_LIBOS_CANTREADPWD; return False; } @@ -225,14 +244,15 @@ static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context au /* CIFS doesn't use addresses in tickets. This would break NAT. JRA */ - p_packet->length = ticket->length; - p_packet->data = (char *)ticket->data; + packet.length = ticket->length; + packet.data = (char *)ticket->data; /* We need to setup a auth context with each possible encoding type in turn. */ for (i=0;enctypes[i];i++) { krb5_keyblock *key = NULL; if (!(key = SMB_MALLOC_P(krb5_keyblock))) { + ret = ENOMEM; goto out; } @@ -243,7 +263,7 @@ static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context au krb5_auth_con_setuseruserkey(context, auth_context, key); - if (!(ret = krb5_rd_req(context, &auth_context, p_packet, + if (!(ret = krb5_rd_req(context, &auth_context, &packet, NULL, NULL, NULL, pp_tkt))) { DEBUG(10,("ads_secrets_verify_ticket: enc type [%u] decrypted message !\n", @@ -260,7 +280,8 @@ static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context au /* successfully decrypted but ticket is just not valid at the moment */ if (ret == KRB5KRB_AP_ERR_TKT_NYV || - ret == KRB5KRB_AP_ERR_TKT_EXPIRED) { + ret == KRB5KRB_AP_ERR_TKT_EXPIRED || + ret == KRB5KRB_AP_ERR_SKEW) { break; } @@ -270,7 +291,7 @@ static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context au out: SAFE_FREE(password_s); - + *perr = ret; return auth_ok; } @@ -280,9 +301,11 @@ static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context au ***********************************************************************************/ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, - const char *realm, time_t time_offset, - const DATA_BLOB *ticket, - char **principal, PAC_DATA **pac_data, + const char *realm, + time_t time_offset, + const DATA_BLOB *ticket, + char **principal, + PAC_DATA **pac_data, DATA_BLOB *ap_rep, DATA_BLOB *session_key) { @@ -296,20 +319,22 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, krb5_rcache rcache = NULL; krb5_keyblock *keyblock = NULL; time_t authtime; - int ret; - + krb5_error_code ret = 0; + krb5_principal host_princ = NULL; krb5_const_principal client_principal = NULL; char *host_princ_s = NULL; - BOOL got_replay_mutex = False; - BOOL auth_ok = False; + BOOL got_replay_mutex = False; BOOL got_auth_data = False; ZERO_STRUCT(packet); ZERO_STRUCT(auth_data); - ZERO_STRUCTP(ap_rep); - ZERO_STRUCTP(session_key); + + *principal = NULL; + *pac_data = NULL; + *ap_rep = data_blob(NULL,0); + *session_key = data_blob(NULL,0); initialize_krb5_error_table(); ret = krb5_init_context(&context); @@ -339,6 +364,10 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, } asprintf(&host_princ_s, "%s$", global_myname()); + if (!host_princ_s) { + goto out; + } + strlower_m(host_princ_s); ret = smb_krb5_parse_name(context, host_princ_s, &host_princ); if (ret) { @@ -353,6 +382,7 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, if (!grab_server_mutex("replay cache mutex")) { DEBUG(1,("ads_verify_ticket: unable to protect replay cache with mutex.\n")); + ret = KRB5_CC_IO; goto out; } @@ -375,11 +405,11 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, } if (lp_use_kerberos_keytab()) { - auth_ok = ads_keytab_verify_ticket(context, auth_context, ticket, &packet, &tkt, &keyblock); + auth_ok = ads_keytab_verify_ticket(context, auth_context, ticket, &tkt, &keyblock, &ret); } if (!auth_ok) { auth_ok = ads_secrets_verify_ticket(context, auth_context, host_princ, - ticket, &packet, &tkt, &keyblock); + ticket, &tkt, &keyblock, &ret); } release_server_mutex(); @@ -395,6 +425,15 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, if (!auth_ok) { DEBUG(3,("ads_verify_ticket: krb5_rd_req with auth failed (%s)\n", error_message(ret))); + /* Try map the error return in case it's something like + * a clock skew error. + */ + sret = krb5_to_nt_status(ret); + if (NT_STATUS_IS_OK(sret) || NT_STATUS_EQUAL(sret,NT_STATUS_UNSUCCESSFUL)) { + sret = NT_STATUS_LOGON_FAILURE; + } + DEBUG(10,("ads_verify_ticket: returning error %s\n", + nt_errstr(sret) )); goto out; } @@ -409,8 +448,10 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, } *ap_rep = data_blob(packet.data, packet.length); - SAFE_FREE(packet.data); - packet.length = 0; + if (packet.data) { + kerberos_free_data_contents(context, &packet); + ZERO_STRUCT(packet); + } get_krb5_smb_session_key(context, auth_context, session_key, True); dump_data_pw("SMB session key (from ticket)\n", session_key->data, session_key->length); diff --git a/source3/libads/krb5_errs.c b/source3/libads/krb5_errs.c index 89cfc2d143..c153bee96e 100644 --- a/source3/libads/krb5_errs.c +++ b/source3/libads/krb5_errs.c @@ -59,6 +59,8 @@ static const struct { {KRB5_CC_NOTFOUND, NT_STATUS_NO_SUCH_FILE}, {KRB5_FCC_NOFILE, NT_STATUS_NO_SUCH_FILE}, {KRB5KDC_ERR_NONE, NT_STATUS_OK}, + {KRB5_RC_MALLOC, NT_STATUS_NO_MEMORY}, + {ENOMEM, NT_STATUS_NO_MEMORY}, {0, NT_STATUS_OK} }; -- cgit From 7d77dd9db600a4b2ee11913bf8169224c2d9424a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 15 Mar 2007 21:53:53 +0000 Subject: r21847: Fix memory leaks in error paths (and in main code path in one case...) in sasl bind. Wonder why coverity didn't find these ? Jeremy. (This used to be commit 89bdd30e4b2bb9dbc2ab57c54be8c6d01cae5a26) --- source3/libads/sasl.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 812f3961f1..bdc4f2e276 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -311,9 +311,9 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) int gss_rc, rc; uint8 *p; uint32 max_msg_size = 0; - char *sname; + char *sname = NULL; ADS_STATUS status; - krb5_principal principal; + krb5_principal principal = NULL; krb5_context ctx = NULL; krb5_enctype enc_types[] = { #ifdef ENCTYPE_ARCFOUR_HMAC @@ -331,24 +331,32 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) initialize_krb5_error_table(); status = ADS_ERROR_KRB5(krb5_init_context(&ctx)); if (!ADS_ERR_OK(status)) { + SAFE_FREE(sname); return status; } status = ADS_ERROR_KRB5(krb5_set_default_tgs_ktypes(ctx, enc_types)); if (!ADS_ERR_OK(status)) { + SAFE_FREE(sname); + krb5_free_context(ctx); return status; } status = ADS_ERROR_KRB5(smb_krb5_parse_name(ctx, sname, &principal)); if (!ADS_ERR_OK(status)) { + SAFE_FREE(sname); + krb5_free_context(ctx); return status; } - free(sname); - krb5_free_context(ctx); - input_name.value = &principal; input_name.length = sizeof(principal); gss_rc = gss_import_name(&minor_status, &input_name, &nt_principal, &serv_name); + + /* We've finished with principal and sname now. */ + SAFE_FREE(sname); + krb5_free_principal(ctx, principal); + krb5_free_context(ctx); + if (gss_rc) { return ADS_ERROR_GSS(gss_rc, minor_status); } -- cgit From b74cb6740f78b9b2c02eb3bc0afb1b7378ac0bc2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 15 Mar 2007 22:11:13 +0000 Subject: r21850: After Jerry explained to me the HORRIBLE way in which the MIT gss libraries *SUCK*, move the frees to the end of the function so MIT doesn't segfault..... Add a comment so that another engineer knows why I did this. Jeremy. (This used to be commit 1a2be06d4a1131952a97f94b05ae69b1dce4c300) --- source3/libads/sasl.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index bdc4f2e276..013985a121 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -352,12 +352,19 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) gss_rc = gss_import_name(&minor_status, &input_name, &nt_principal, &serv_name); - /* We've finished with principal and sname now. */ + /* + * The MIT libraries have a *HORRIBLE* bug - input_value.value needs + * to point to the *address* of the krb5_principal, and the gss libraries + * to a shallow copy of the krb5_principal pointer - so we need to keep + * the krb5_principal around until we do the gss_release_name. MIT *SUCKS* ! + * Just one more way in which MIT engineers screwed me over.... JRA. + */ + SAFE_FREE(sname); - krb5_free_principal(ctx, principal); - krb5_free_context(ctx); if (gss_rc) { + krb5_free_principal(ctx, principal); + krb5_free_context(ctx); return ADS_ERROR_GSS(gss_rc, minor_status); } @@ -415,8 +422,6 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) if (gss_rc == 0) break; } - gss_release_name(&minor_status, &serv_name); - gss_rc = gss_unwrap(&minor_status,context_handle,&input_token,&output_token, (int *)&conf_state,NULL); if (gss_rc) { @@ -471,6 +476,11 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) gss_release_buffer(&minor_status, &input_token); failed: + + gss_release_name(&minor_status, &serv_name); + krb5_free_principal(ctx, principal); + krb5_free_context(ctx); + if(scred) ber_bvfree(scred); return status; -- cgit From b067d986b4f45996a3920c2412210a397871af06 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 16 Mar 2007 15:48:07 +0000 Subject: r21855: Fix a memleak in the krb5 locator and comment out gfree_all() which doesn't make sense as long as it doesn't work as an lp_unload(). Guenther (This used to be commit 128ea9bebbb215e41d2f0576e1a73c6a362b7467) --- source3/libads/smb_krb5_locator.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/smb_krb5_locator.c b/source3/libads/smb_krb5_locator.c index 9861511714..be14a12697 100644 --- a/source3/libads/smb_krb5_locator.c +++ b/source3/libads/smb_krb5_locator.c @@ -239,7 +239,7 @@ void smb_krb5_locator_close(void *private_data) { DEBUG(10,("smb_krb5_locator_close: called\n")); - gfree_all(); + /* gfree_all(); */ } /** @@ -324,7 +324,7 @@ krb5_error_code smb_krb5_locator_lookup(void *private_data, /* if we didn't found any KDCs on our site go to the main list */ if (NT_STATUS_IS_OK(status) && sitename && (count == 0)) { - ip_list = NULL; + SAFE_FREE(ip_list); SAFE_FREE(sitename); status = get_kdc_list(realm, NULL, &ip_list, &count); } @@ -365,6 +365,8 @@ krb5_error_code smb_krb5_locator_lookup(void *private_data, } } + SAFE_FREE(ip_list); + return ret; } -- cgit From 42b2ddec8fd1dbc29911eac0e04900b6e7930229 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 16 Mar 2007 22:40:51 +0000 Subject: r21863: Fix debug messages with incorrect function name. Jeremy. (This used to be commit d432d81c8321a4444b970169a5c7c3c5709de8e5) --- source3/libads/kerberos_keytab.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c index ba1a916567..0ad225fbeb 100644 --- a/source3/libads/kerberos_keytab.c +++ b/source3/libads/kerberos_keytab.c @@ -55,20 +55,20 @@ static int smb_krb5_kt_add_entry( krb5_context context, krb5_keytab keytab, ret = smb_krb5_parse_name(context, princ_s, &princ); if (ret) { - DEBUG(1,("ads_keytab_add_entry: smb_krb5_parse_name(%s) failed (%s)\n", princ_s, error_message(ret))); + DEBUG(1,("smb_krb5_kt_add_entry: smb_krb5_parse_name(%s) failed (%s)\n", princ_s, error_message(ret))); goto out; } /* Seek and delete old keytab entries */ ret = krb5_kt_start_seq_get(context, keytab, &cursor); if (ret != KRB5_KT_END && ret != ENOENT ) { - DEBUG(3,("ads_keytab_add_entry: Will try to delete old keytab entries\n")); + DEBUG(3,("smb_krb5_kt_add_entry: Will try to delete old keytab entries\n")); while(!krb5_kt_next_entry(context, keytab, &kt_entry, &cursor)) { BOOL compare_name_ok = False; ret = smb_krb5_unparse_name(context, kt_entry.principal, &ktprinc); if (ret) { - DEBUG(1,("ads_keytab_add_entry: smb_krb5_unparse_name failed (%s)\n", + DEBUG(1,("smb_krb5_kt_add_entry: smb_krb5_unparse_name failed (%s)\n", error_message(ret))); goto out; } @@ -89,7 +89,7 @@ static int smb_krb5_kt_add_entry( krb5_context context, krb5_keytab keytab, #endif if (!compare_name_ok) { - DEBUG(10,("ads_keytab_add_entry: ignoring keytab entry principal %s, kvno = %d\n", + DEBUG(10,("smb_krb5_kt_add_entry: ignoring keytab entry principal %s, kvno = %d\n", ktprinc, kt_entry.vno)); } @@ -97,39 +97,39 @@ static int smb_krb5_kt_add_entry( krb5_context context, krb5_keytab keytab, if (compare_name_ok) { if (kt_entry.vno == kvno - 1) { - DEBUG(5,("ads_keytab_add_entry: Saving previous (kvno %d) entry for principal: %s.\n", + DEBUG(5,("smb_krb5_kt_add_entry: Saving previous (kvno %d) entry for principal: %s.\n", kvno - 1, princ_s)); } else { - DEBUG(5,("ads_keytab_add_entry: Found old entry for principal: %s (kvno %d) - trying to remove it.\n", + DEBUG(5,("smb_krb5_kt_add_entry: Found old entry for principal: %s (kvno %d) - trying to remove it.\n", princ_s, kt_entry.vno)); ret = krb5_kt_end_seq_get(context, keytab, &cursor); ZERO_STRUCT(cursor); if (ret) { - DEBUG(1,("ads_keytab_add_entry: krb5_kt_end_seq_get() failed (%s)\n", + DEBUG(1,("smb_krb5_kt_add_entry: krb5_kt_end_seq_get() failed (%s)\n", error_message(ret))); goto out; } ret = krb5_kt_remove_entry(context, keytab, &kt_entry); if (ret) { - DEBUG(1,("ads_keytab_add_entry: krb5_kt_remove_entry failed (%s)\n", + DEBUG(1,("smb_krb5_kt_add_entry: krb5_kt_remove_entry failed (%s)\n", error_message(ret))); goto out; } - DEBUG(5,("ads_keytab_add_entry: removed old entry for principal: %s (kvno %d).\n", + DEBUG(5,("smb_krb5_kt_add_entry: removed old entry for principal: %s (kvno %d).\n", princ_s, kt_entry.vno)); ret = krb5_kt_start_seq_get(context, keytab, &cursor); if (ret) { - DEBUG(1,("ads_keytab_add_entry: krb5_kt_start_seq failed (%s)\n", + DEBUG(1,("smb_krb5_kt_add_entry: krb5_kt_start_seq failed (%s)\n", error_message(ret))); goto out; } ret = smb_krb5_kt_free_entry(context, &kt_entry); ZERO_STRUCT(kt_entry); if (ret) { - DEBUG(1,("ads_keytab_add_entry: krb5_kt_remove_entry failed (%s)\n", + DEBUG(1,("smb_krb5_kt_add_entry: krb5_kt_remove_entry failed (%s)\n", error_message(ret))); goto out; } @@ -141,7 +141,7 @@ static int smb_krb5_kt_add_entry( krb5_context context, krb5_keytab keytab, ret = smb_krb5_kt_free_entry(context, &kt_entry); ZERO_STRUCT(kt_entry); if (ret) { - DEBUG(1,("ads_keytab_add_entry: smb_krb5_kt_free_entry failed (%s)\n", error_message(ret))); + DEBUG(1,("smb_krb5_kt_add_entry: smb_krb5_kt_free_entry failed (%s)\n", error_message(ret))); goto out; } } @@ -149,7 +149,7 @@ static int smb_krb5_kt_add_entry( krb5_context context, krb5_keytab keytab, ret = krb5_kt_end_seq_get(context, keytab, &cursor); ZERO_STRUCT(cursor); if (ret) { - DEBUG(1,("ads_keytab_add_entry: krb5_kt_end_seq_get failed (%s)\n",error_message(ret))); + DEBUG(1,("smb_krb5_kt_add_entry: krb5_kt_end_seq_get failed (%s)\n",error_message(ret))); goto out; } } @@ -180,13 +180,13 @@ static int smb_krb5_kt_add_entry( krb5_context context, krb5_keytab keytab, kt_entry.principal = princ; kt_entry.vno = kvno; - DEBUG(3,("ads_keytab_add_entry: adding keytab entry for (%s) with encryption type (%d) and version (%d)\n", + DEBUG(3,("smb_krb5_kt_add_entry: adding keytab entry for (%s) with encryption type (%d) and version (%d)\n", princ_s, enctypes[i], kt_entry.vno)); ret = krb5_kt_add_entry(context, keytab, &kt_entry); krb5_free_keyblock_contents(context, keyp); ZERO_STRUCT(kt_entry); if (ret) { - DEBUG(1,("ads_keytab_add_entry: adding entry to keytab failed (%s)\n", error_message(ret))); + DEBUG(1,("smb_krb5_kt_add_entry: adding entry to keytab failed (%s)\n", error_message(ret))); goto out; } } -- cgit From 8c395be5e514a28f13608a462c0c0e8417e21160 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 21 Mar 2007 23:49:57 +0000 Subject: r21922: Fixed the build by rather horrid means. I really need to restructure libsmb/smb_signing.c so it isn't in the base libs path but lives in libsmb instead (like smb_seal.c does). Jeremy. (This used to be commit 1b828f051d0782201f697de15ff973bd6b097d5b) --- source3/libads/ads_status.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_status.c b/source3/libads/ads_status.c index 017d38c600..d022e5b323 100644 --- a/source3/libads/ads_status.c +++ b/source3/libads/ads_status.c @@ -84,6 +84,10 @@ NTSTATUS ads_ntstatus(ADS_STATUS status) #ifdef HAVE_KRB5 case ENUM_ADS_ERROR_KRB5: return krb5_to_nt_status(status.err.rc); +#endif +#ifdef HAVE_GSSAPI + case ENUM_ADS_ERROR_GSS: + return NT_STATUS_UNSUCCESSFUL; #endif default: break; @@ -143,5 +147,3 @@ const char *ads_errstr(ADS_STATUS status) } } - - -- cgit From 3adeddcc4a948ec230db7ea4a6b0d3f1640ff3a6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 27 Mar 2007 00:00:50 +0000 Subject: r21967: Add conversion from gss errors to nt status. Jeremy (This used to be commit 8ba138efd097b08dcfe98f99b67c77579babf250) --- source3/libads/ads_status.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_status.c b/source3/libads/ads_status.c index d022e5b323..0e1a2d55d5 100644 --- a/source3/libads/ads_status.c +++ b/source3/libads/ads_status.c @@ -87,7 +87,7 @@ NTSTATUS ads_ntstatus(ADS_STATUS status) #endif #ifdef HAVE_GSSAPI case ENUM_ADS_ERROR_GSS: - return NT_STATUS_UNSUCCESSFUL; + return map_nt_error_from_gss(status.err.rc, status.minor_status); #endif default: break; @@ -145,5 +145,14 @@ const char *ads_errstr(ADS_STATUS status) default: return "Unknown ADS error type!? (not compiled in?)"; } +} +#ifdef HAVE_GSSAPI +NTSTATUS gss_err_to_ntstatus(OM_uint32 maj, OM_uint32 min) +{ + ADS_STATUS adss = ADS_ERROR_GSS(maj, min); + DEBUG(10,("gss_err_to_ntstatus: Error %s\n", + ads_errstr(adss) )); + return ads_ntstatus(adss); } +#endif -- cgit From 9d34ee1c8b2977986518f3720ae0e98c487cda47 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 27 Mar 2007 00:29:46 +0000 Subject: r21968: Don't use gss-types in proto headers. Jeremy. (This used to be commit 829580414d89ff4aa0f45906e455849c55f508b1) --- source3/libads/ads_status.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_status.c b/source3/libads/ads_status.c index 0e1a2d55d5..48c03a6a14 100644 --- a/source3/libads/ads_status.c +++ b/source3/libads/ads_status.c @@ -148,7 +148,7 @@ const char *ads_errstr(ADS_STATUS status) } #ifdef HAVE_GSSAPI -NTSTATUS gss_err_to_ntstatus(OM_uint32 maj, OM_uint32 min) +NTSTATUS gss_err_to_ntstatus(uint32 maj, uint32 min) { ADS_STATUS adss = ADS_ERROR_GSS(maj, min); DEBUG(10,("gss_err_to_ntstatus: Error %s\n", -- cgit From 98c300ab90cc7775818c333931f1f923f9eb7763 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 4 Apr 2007 14:50:39 +0000 Subject: r22078: fix memory leak in not often used code, we only use it if the server doesn't support GSS-SPNEGO in SASL can someone please review this, maybe it's also for 3.0.25 metze (This used to be commit 8c6930b7013b185af0530b04a7d5a49bc2ce7831) --- source3/libads/sasl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 013985a121..ce000a1306 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -301,7 +301,7 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) uint32 minor_status; gss_name_t serv_name; gss_buffer_desc input_name; - gss_ctx_id_t context_handle; + gss_ctx_id_t context_handle = GSS_C_NO_CONTEXT; gss_OID mech_type = GSS_C_NULL_OID; gss_buffer_desc output_token, input_token; uint32 ret_flags, conf_state; @@ -368,8 +368,6 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) return ADS_ERROR_GSS(gss_rc, minor_status); } - context_handle = GSS_C_NO_CONTEXT; - input_token.value = NULL; input_token.length = 0; @@ -478,6 +476,8 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) failed: gss_release_name(&minor_status, &serv_name); + if (context_handle != GSS_C_NO_CONTEXT) + gss_delete_sec_context(&min_status, &context_handle, GSS_C_NO_BUFFER); krb5_free_principal(ctx, principal); krb5_free_context(ctx); -- cgit From 4899c6b8069885df517de00b9608adb70c4a58be Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 4 Apr 2007 17:38:12 +0000 Subject: r22079: Tsk, tsk, Metze didn't compile before check-in :-). Merge the memory leak fix (with fix :-) to 3.0.25. Jeremy. (This used to be commit ab3150fe4ed2a629eb371db5f43ae09b9c583a64) --- source3/libads/sasl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index ce000a1306..0067a19d3b 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -477,7 +477,7 @@ failed: gss_release_name(&minor_status, &serv_name); if (context_handle != GSS_C_NO_CONTEXT) - gss_delete_sec_context(&min_status, &context_handle, GSS_C_NO_BUFFER); + gss_delete_sec_context(&minor_status, &context_handle, GSS_C_NO_BUFFER); krb5_free_principal(ctx, principal); krb5_free_context(ctx); -- cgit From eceb926df94063e91c5abc96f52a1bc7b45ce290 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 5 Apr 2007 12:30:23 +0000 Subject: r22092: - make spnego_parse_auth_response() more generic and not specific for NTLMSSP - it's possible that the server sends a mechOID and authdata if negResult != SPNEGO_NEG_RESULT_INCOMPLETE, but we still force the mechOID to be present if negResult == SPNEGO_NEG_RESULT_INCOMPLETE metze (This used to be commit e9f2aa22f90208a5e530ef3b68664151960a0a22) --- source3/libads/sasl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 0067a19d3b..b5f92044ef 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -114,7 +114,7 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) } data_blob_free(&tmp_blob); } else if (rc == LDAP_SASL_BIND_IN_PROGRESS) { - if (!spnego_parse_auth_response(blob, nt_status, + if (!spnego_parse_auth_response(blob, nt_status, OID_NTLMSSP, &blob_in)) { ntlmssp_end(&ntlmssp_state); -- cgit From 725fcf3461f7684554938c5571a5013408ff431c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 6 Apr 2007 21:55:44 +0000 Subject: r22112: Fix memleak pointed out by Steven Danneman . Jeremy. (This used to be commit 7c45bd3a47fc2b24c5f1351a241ace2201c857d2) --- source3/libads/ldap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 1d08a01a26..b2ca68f67f 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2258,7 +2258,6 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) LDAPMessage *msg, const char *field, SEC_DESC **sd) { struct berval **values; - prs_struct ps; BOOL ret = False; values = ldap_get_values_len(ads->ld, msg, field); @@ -2266,11 +2265,13 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) if (!values) return False; if (values[0]) { + prs_struct ps; prs_init(&ps, values[0]->bv_len, mem_ctx, UNMARSHALL); prs_copy_data_in(&ps, values[0]->bv_val, values[0]->bv_len); prs_set_offset(&ps,0); ret = sec_io_desc("sd", sd, &ps, 1); + prs_mem_free(&ps); } ldap_value_free_len(values); -- cgit From 78c57f59ac7d47425ebb450205efc981575aab8d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 10 Apr 2007 16:04:22 +0000 Subject: r22153: fix LDAP SASL "GSSAPI" bind against w2k3, this isn't critical because we try "GSS-SPNEGO" first and all windows version support that. metze (This used to be commit 34a5badbded0b2537ee854287931e2a7dc3aeb37) --- source3/libads/sasl.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index b5f92044ef..2fc66bd929 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -441,7 +441,8 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) gss_release_buffer(&minor_status, &output_token); - output_token.value = SMB_MALLOC(strlen(ads->config.bind_path) + 8); + output_token.length = 4; + output_token.value = SMB_MALLOC(output_token.length); p = (uint8 *)output_token.value; *p++ = 1; /* no sign & seal selection */ @@ -449,10 +450,14 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) *p++ = max_msg_size>>16; *p++ = max_msg_size>>8; *p++ = max_msg_size; - snprintf((char *)p, strlen(ads->config.bind_path)+4, "dn:%s", ads->config.bind_path); - p += strlen((const char *)p); - - output_token.length = PTR_DIFF(p, output_token.value); + /* + * we used to add sprintf("dn:%s", ads->config.bind_path) here. + * but using ads->config.bind_path is the wrong! It should be + * the DN of the user object! + * + * w2k3 gives an error when we send an incorrect DN, but sending nothing + * is ok and matches the information flow used in GSS-SPNEGO. + */ gss_rc = gss_wrap(&minor_status, context_handle,0,GSS_C_QOP_DEFAULT, &output_token, (int *)&conf_state, -- cgit From 8040fec0accd93b7932c1c81520540ea46c33eb6 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sun, 22 Apr 2007 15:13:50 +0000 Subject: r22459: Adding ads_get_dn_from_extended_dn(), in preparation of making ranged LDAP queries more generic. Michael, feel free to overwrite these and the following. Guenther (This used to be commit 0475b8eea99ebb467e52225ad54f4302a77376b9) --- source3/libads/ldap.c | 40 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index b2ca68f67f..6707cbd4d0 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2677,24 +2677,58 @@ ADS_STATUS ads_upn_suffixes(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char ***suffix return status; } +/** + * pull a dn from an extended dn string + * @param mem_ctx TALLOC_CTX + * @param extended_dn string + * @param dn pointer to the dn + * @return boolean inidicating success + **/ +BOOL ads_get_dn_from_extended_dn(TALLOC_CTX *mem_ctx, + const char *extended_dn, + char **dn) +{ + char *p; + pstring tok; + + if (!extended_dn) { + return False; + } + + while (next_token(&extended_dn, tok, ";", sizeof(tok))) { + p = tok; + } + + if ((*dn = talloc_strdup(mem_ctx, p)) == NULL) { + return False; + } + + return True; +} + /** * pull a DOM_SID from an extended dn string * @param mem_ctx TALLOC_CTX + * @param extended_dn string * @param flags string type of extended_dn * @param sid pointer to a DOM_SID * @return boolean inidicating success **/ BOOL ads_get_sid_from_extended_dn(TALLOC_CTX *mem_ctx, - const char *dn, + const char *extended_dn, enum ads_extended_dn_flags flags, DOM_SID *sid) { - char *p, *q; + char *p, *q, *dn; - if (!dn) { + if (!extended_dn) { return False; } + /* otherwise extended_dn gets stripped off */ + if ((dn = talloc_strdup(mem_ctx, extended_dn)) == NULL) { + return False; + } /* * ADS_EXTENDED_DN_HEX_STRING: * ;;CN=gd,OU=berlin,OU=suse,DC=ber,DC=suse,DC=de -- cgit From 56f6336fd4a8e929bf18f1c1c3b3f8f54ee341f5 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sun, 22 Apr 2007 15:15:00 +0000 Subject: r22460: Adding a generic ads_ranged_search() function. Guenther (This used to be commit b8828ea2516876fe5dd76083864418db2f042be0) --- source3/libads/ldap_utils.c | 174 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 173 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap_utils.c b/source3/libads/ldap_utils.c index 1da51b3c5c..383b652f97 100644 --- a/source3/libads/ldap_utils.c +++ b/source3/libads/ldap_utils.c @@ -46,7 +46,7 @@ static ADS_STATUS ads_do_search_retry_internal(ADS_STRUCT *ads, const char *bind bp = SMB_STRDUP(bind_path); if (!bp) { - return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + return ADS_ERROR(LDAP_NO_MEMORY); } *res = NULL; @@ -161,6 +161,30 @@ static ADS_STATUS ads_do_search_retry_internal(ADS_STRUCT *ads, const char *bind return ads_do_search_retry_args(ads, dn, LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &args, res); +} + + ADS_STATUS ads_search_retry_extended_dn_ranged(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, + const char *dn, + const char **attrs, + enum ads_extended_dn_flags flags, + char ***strings, + size_t *num_strings) +{ + ads_control args; + + args.control = ADS_EXTENDED_DN_OID; + args.val = flags; + args.critical = True; + + /* we can only range process one attribute */ + if (!attrs || !attrs[0] || attrs[1]) { + return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); + } + + return ads_ranged_search(ads, mem_ctx, LDAP_SCOPE_BASE, dn, + "(objectclass=*)", &args, attrs[0], + strings, num_strings); + } ADS_STATUS ads_search_retry_sid(ADS_STRUCT *ads, LDAPMessage **res, @@ -187,4 +211,152 @@ static ADS_STATUS ads_do_search_retry_internal(ADS_STRUCT *ads, const char *bind return status; } +ADS_STATUS ads_ranged_search(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + int scope, + const char *base, + const char *filter, + void *args, + const char *range_attr, + char ***strings, + size_t *num_strings) +{ + ADS_STATUS status; + uint32 first_usn; + int num_retries = 0; + const char **attrs; + BOOL more_values = False; + + *num_strings = 0; + *strings = NULL; + + attrs = TALLOC_ARRAY(mem_ctx, const char *, 3); + ADS_ERROR_HAVE_NO_MEMORY(attrs); + + attrs[0] = talloc_strdup(mem_ctx, range_attr); + attrs[1] = talloc_strdup(mem_ctx, "usnChanged"); + attrs[2] = NULL; + + ADS_ERROR_HAVE_NO_MEMORY(attrs[0]); + ADS_ERROR_HAVE_NO_MEMORY(attrs[1]); + + do { + status = ads_ranged_search_internal(ads, mem_ctx, + scope, base, filter, + attrs, args, range_attr, + strings, num_strings, + &first_usn, &num_retries, + &more_values); + + if (NT_STATUS_EQUAL(STATUS_MORE_ENTRIES, ads_ntstatus(status))) { + continue; + } + + if (!ADS_ERR_OK(status)) { + *num_strings = 0; + strings = NULL; + goto done; + } + + } while (more_values); + + done: + DEBUG(10,("returning with %d strings\n", (int)*num_strings)); + + return status; +} + +ADS_STATUS ads_ranged_search_internal(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + int scope, + const char *base, + const char *filter, + const char **attrs, + void *args, + const char *range_attr, + char ***strings, + size_t *num_strings, + uint32 *first_usn, + int *num_retries, + BOOL *more_values) +{ + LDAPMessage *res = NULL; + ADS_STATUS status; + int count; + uint32 current_usn; + + DEBUG(10, ("Searching for attrs[0] = %s, attrs[1] = %s\n", attrs[0], attrs[1])); + + *more_values = False; + + status = ads_do_search_retry_internal(ads, base, scope, filter, attrs, args, &res); + + if (!ADS_ERR_OK(status)) { + DEBUG(1,("ads_search: %s\n", + ads_errstr(status))); + return status; + } + + if (!res) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + + count = ads_count_replies(ads, res); + if (count == 0) { + ads_msgfree(ads, res); + return ADS_ERROR(LDAP_SUCCESS); + } + + if (*num_strings == 0) { + if (!ads_pull_uint32(ads, res, "usnChanged", first_usn)) { + DEBUG(1, ("could not pull first usnChanged!\n")); + ads_msgfree(ads, res); + return ADS_ERROR(LDAP_NO_MEMORY); + } + } + + if (!ads_pull_uint32(ads, res, "usnChanged", ¤t_usn)) { + DEBUG(1, ("could not pull current usnChanged!\n")); + ads_msgfree(ads, res); + return ADS_ERROR(LDAP_NO_MEMORY); + } + + if (*first_usn != current_usn) { + DEBUG(5, ("USN on this record changed" + " - restarting search\n")); + if (*num_retries < 5) { + (*num_retries)++; + *num_strings = 0; + ads_msgfree(ads, res); + return ADS_ERROR_NT(STATUS_MORE_ENTRIES); + } else { + DEBUG(5, ("USN on this record changed" + " - restarted search too many times, aborting!\n")); + ads_msgfree(ads, res); + return ADS_ERROR(LDAP_NO_MEMORY); + } + } + + *strings = ads_pull_strings_range(ads, mem_ctx, res, + range_attr, + *strings, + &attrs[0], + num_strings, + more_values); + + ads_msgfree(ads, res); + + /* paranoia checks */ + if (*strings == NULL && *more_values) { + DEBUG(0,("no strings found but more values???\n")); + return ADS_ERROR(LDAP_NO_MEMORY); + } + if (*num_strings == 0 && *more_values) { + DEBUG(0,("no strings found but more values???\n")); + return ADS_ERROR(LDAP_NO_MEMORY); + } + + return (*more_values) ? ADS_ERROR_NT(STATUS_MORE_ENTRIES) : ADS_ERROR(LDAP_SUCCESS); +} + #endif -- cgit From 1ee9650a1dfa28badac1f37b4c14fca920c6330c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 23 Apr 2007 08:40:54 +0000 Subject: r22479: Add "net ads keytab list". Guenther (This used to be commit 9ec76c542775ae58ff03f42ebfa1acc1a63a1bb1) --- source3/libads/kerberos_keytab.c | 112 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c index 0ad225fbeb..d99e322b99 100644 --- a/source3/libads/kerberos_keytab.c +++ b/source3/libads/kerberos_keytab.c @@ -691,4 +691,116 @@ done: } return ret; } + +/********************************************************************** + List system keytab. +***********************************************************************/ + +int ads_keytab_list(void) +{ + krb5_error_code ret = 0; + krb5_context context = NULL; + krb5_keytab keytab = NULL; + krb5_kt_cursor cursor; + krb5_keytab_entry kt_entry; + char keytab_name[MAX_KEYTAB_NAME_LEN]; + + ZERO_STRUCT(kt_entry); + ZERO_STRUCT(cursor); + + initialize_krb5_error_table(); + ret = krb5_init_context(&context); + if (ret) { + DEBUG(1,("ads_keytab_list: could not krb5_init_context: %s\n",error_message(ret))); + return ret; + } +#if 0 /* HAVE_WRFILE_KEYTAB */ + keytab_name[0] = 'W'; + keytab_name[1] = 'R'; + ret = krb5_kt_default_name(context, (char *) &keytab_name[2], MAX_KEYTAB_NAME_LEN - 4); +#else + ret = krb5_kt_default_name(context, (char *) &keytab_name[0], MAX_KEYTAB_NAME_LEN - 2); +#endif + if (ret) { + DEBUG(1,("ads_keytab_list: krb5_kt_default failed (%s)\n", error_message(ret))); + goto out; + } + DEBUG(3,("ads_keytab_list: Using default keytab: %s\n", (char *) &keytab_name)); + ret = krb5_kt_resolve(context, (char *) &keytab_name, &keytab); + if (ret) { + DEBUG(1,("ads_keytab_list: krb5_kt_resolve failed (%s)\n", error_message(ret))); + goto out; + } + + ret = krb5_kt_start_seq_get(context, keytab, &cursor); + if (ret) { + goto out; + } + + printf("Vno Type Principal\n"); + + while (krb5_kt_next_entry(context, keytab, &kt_entry, &cursor) == 0) { + + char *princ_s = NULL; + char *etype_s = NULL; + krb5_enctype enctype = 0; + + ret = smb_krb5_unparse_name(context, kt_entry.principal, &princ_s); + if (ret) { + goto out; + } + + enctype = smb_get_enctype_from_kt_entry(&kt_entry); + + ret = smb_krb5_enctype_to_string(context, enctype, &etype_s); + if (ret) { + SAFE_FREE(princ_s); + goto out; + } + + printf("%3d %s\t\t %s\n", kt_entry.vno, etype_s, princ_s); + + SAFE_FREE(princ_s); + SAFE_FREE(etype_s); + + ret = smb_krb5_kt_free_entry(context, &kt_entry); + if (ret) { + goto out; + } + } + + ret = krb5_kt_end_seq_get(context, keytab, &cursor); + if (ret) { + goto out; + } + + /* Ensure we don't double free. */ + ZERO_STRUCT(kt_entry); + ZERO_STRUCT(cursor); +out: + + { + krb5_keytab_entry zero_kt_entry; + ZERO_STRUCT(zero_kt_entry); + if (memcmp(&zero_kt_entry, &kt_entry, sizeof(krb5_keytab_entry))) { + smb_krb5_kt_free_entry(context, &kt_entry); + } + } + { + krb5_kt_cursor zero_csr; + ZERO_STRUCT(zero_csr); + if ((memcmp(&cursor, &zero_csr, sizeof(krb5_kt_cursor)) != 0) && keytab) { + krb5_kt_end_seq_get(context, keytab, &cursor); + } + } + + if (keytab) { + krb5_kt_close(context, keytab); + } + if (context) { + krb5_free_context(context); + } + return ret; +} + #endif /* HAVE_KRB5 */ -- cgit From be8b0685a55700c6bce3681734800ec6434b0364 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 30 Apr 2007 02:39:34 +0000 Subject: r22589: Make TALLOC_ARRAY consistent across all uses. Jeremy. (This used to be commit 8968808c3b5b0208cbad9ac92eaf948f2c546dd9) --- source3/libads/dns.c | 22 +++++++++++++++------- source3/libads/ldap.c | 12 ++++++++---- 2 files changed, 23 insertions(+), 11 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/dns.c b/source3/libads/dns.c index 008266ea0b..8b031b0e3a 100644 --- a/source3/libads/dns.c +++ b/source3/libads/dns.c @@ -283,9 +283,13 @@ static NTSTATUS dns_send_req( TALLOC_CTX *ctx, const char *name, int q_type, buf_len = resp_len * sizeof(uint8); - if ( (buffer = TALLOC_ARRAY(ctx, uint8, buf_len)) == NULL ) { - DEBUG(0,("ads_dns_lookup_srv: talloc() failed!\n")); - return NT_STATUS_NO_MEMORY; + if (buf_len) { + if ( (buffer = TALLOC_ARRAY(ctx, uint8, buf_len)) == NULL ) { + DEBUG(0,("ads_dns_lookup_srv: talloc() failed!\n")); + return NT_STATUS_NO_MEMORY; + } + } else { + buffer = NULL; } if ( (resp_len = res_query(name, C_IN, q_type, buffer, buf_len)) < 0 ) { @@ -499,10 +503,14 @@ NTSTATUS ads_dns_lookup_ns( TALLOC_CTX *ctx, const char *dnsdomain, struct dns_r DEBUG(4,("ads_dns_lookup_ns: %d records returned in the answer section.\n", answer_count)); - if ( (nsarray = TALLOC_ARRAY(ctx, struct dns_rr_ns, answer_count)) == NULL ) { - DEBUG(0,("ads_dns_lookup_ns: talloc() failure for %d char*'s\n", - answer_count)); - return NT_STATUS_NO_MEMORY; + if (answer_count) { + if ( (nsarray = TALLOC_ARRAY(ctx, struct dns_rr_ns, answer_count)) == NULL ) { + DEBUG(0,("ads_dns_lookup_ns: talloc() failure for %d char*'s\n", + answer_count)); + return NT_STATUS_NO_MEMORY; + } + } else { + nsarray = NULL; } /* now skip the header */ diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 6707cbd4d0..5a34385c32 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2225,10 +2225,14 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) for (i=0; values[i]; i++) /* nop */ ; - (*sids) = TALLOC_ARRAY(mem_ctx, DOM_SID, i); - if (!(*sids)) { - ldap_value_free_len(values); - return 0; + if (i) { + (*sids) = TALLOC_ARRAY(mem_ctx, DOM_SID, i); + if (!(*sids)) { + ldap_value_free_len(values); + return 0; + } + } else { + (*sids) = NULL; } count = 0; -- cgit From 56a5d05b8b285250bdc0e9cc3c8f3c3d8af80382 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 30 Apr 2007 02:51:26 +0000 Subject: r22590: Make TALLOC_ARRAY consistent across all uses. That should be it.... Jeremy. (This used to be commit 603233a98bbf65467c8b4f04719d771c70b3b4c9) --- source3/libads/dns.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/dns.c b/source3/libads/dns.c index 8b031b0e3a..f16cea2555 100644 --- a/source3/libads/dns.c +++ b/source3/libads/dns.c @@ -355,10 +355,14 @@ static NTSTATUS ads_dns_lookup_srv( TALLOC_CTX *ctx, const char *name, struct dn DEBUG(4,("ads_dns_lookup_srv: %d records returned in the answer section.\n", answer_count)); - if ( (dcs = TALLOC_ZERO_ARRAY(ctx, struct dns_rr_srv, answer_count)) == NULL ) { - DEBUG(0,("ads_dns_lookup_srv: talloc() failure for %d char*'s\n", - answer_count)); - return NT_STATUS_NO_MEMORY; + if (answer_count) { + if ( (dcs = TALLOC_ZERO_ARRAY(ctx, struct dns_rr_srv, answer_count)) == NULL ) { + DEBUG(0,("ads_dns_lookup_srv: talloc() failure for %d char*'s\n", + answer_count)); + return NT_STATUS_NO_MEMORY; + } + } else { + dcs = NULL; } /* now skip the header */ -- cgit From 6288491e90e542c02857935a528e9765a636cf2a Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 4 May 2007 09:46:17 +0000 Subject: r22663: Restructure kerberos_kinit_password_ext() error path. Guenther (This used to be commit 997ded4e3f0dc2199b9a66a9485c919c16fbabc6) --- source3/libads/kerberos.c | 86 ++++++++++++++++++----------------------------- 1 file changed, 33 insertions(+), 53 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index b6627075b0..72ff2cbdab 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -73,14 +73,16 @@ int kerberos_kinit_password_ext(const char *principal, krb5_context ctx = NULL; krb5_error_code code = 0; krb5_ccache cc = NULL; - krb5_principal me; + krb5_principal me = NULL; krb5_creds my_creds; krb5_get_init_creds_opt *opt = NULL; smb_krb5_addresses *addr = NULL; + ZERO_STRUCT(my_creds); + initialize_krb5_error_table(); if ((code = krb5_init_context(&ctx))) - return code; + goto out; if (time_offset != 0) { krb5_set_real_time(ctx, time(NULL) + time_offset, 0); @@ -91,21 +93,15 @@ int kerberos_kinit_password_ext(const char *principal, getenv("KRB5_CONFIG"))); if ((code = krb5_cc_resolve(ctx, cache_name ? cache_name : krb5_cc_default_name(ctx), &cc))) { - krb5_free_context(ctx); - return code; + goto out; } if ((code = smb_krb5_parse_name(ctx, principal, &me))) { - krb5_cc_close(ctx, cc); - krb5_free_context(ctx); - return code; + goto out; } - code = smb_krb5_get_init_creds_opt_alloc(ctx, &opt); - if (code) { - krb5_cc_close(ctx, cc); - krb5_free_context(ctx); - return code; + if ((code = smb_krb5_get_init_creds_opt_alloc(ctx, &opt))) { + goto out; } krb5_get_init_creds_opt_set_renew_life(opt, renewable_time); @@ -117,55 +113,29 @@ int kerberos_kinit_password_ext(const char *principal, #ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PAC_REQUEST if (request_pac) { - code = krb5_get_init_creds_opt_set_pac_request(ctx, opt, (krb5_boolean)request_pac); - if (code) { - krb5_cc_close(ctx, cc); - krb5_free_principal(ctx, me); - krb5_free_context(ctx); - return code; + if ((code = krb5_get_init_creds_opt_set_pac_request(ctx, opt, (krb5_boolean)request_pac))) { + goto out; } } #endif if (add_netbios_addr) { - code = smb_krb5_gen_netbios_krb5_address(&addr); - if (code) { - krb5_cc_close(ctx, cc); - krb5_free_principal(ctx, me); - krb5_free_context(ctx); - return code; + if ((code = smb_krb5_gen_netbios_krb5_address(&addr))) { + goto out; } krb5_get_init_creds_opt_set_address_list(opt, addr->addrs); } if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, CONST_DISCARD(char *,password), - kerb_prompter, NULL, 0, NULL, opt))) - { - smb_krb5_get_init_creds_opt_free(ctx, opt); - smb_krb5_free_addresses(ctx, addr); - krb5_cc_close(ctx, cc); - krb5_free_principal(ctx, me); - krb5_free_context(ctx); - return code; + kerb_prompter, NULL, 0, NULL, opt))) { + goto out; } - smb_krb5_get_init_creds_opt_free(ctx, opt); - if ((code = krb5_cc_initialize(ctx, cc, me))) { - smb_krb5_free_addresses(ctx, addr); - krb5_free_cred_contents(ctx, &my_creds); - krb5_cc_close(ctx, cc); - krb5_free_principal(ctx, me); - krb5_free_context(ctx); - return code; + goto out; } if ((code = krb5_cc_store_cred(ctx, cc, &my_creds))) { - krb5_cc_close(ctx, cc); - smb_krb5_free_addresses(ctx, addr); - krb5_free_cred_contents(ctx, &my_creds); - krb5_free_principal(ctx, me); - krb5_free_context(ctx); - return code; + goto out; } if (expire_time) { @@ -175,14 +145,24 @@ int kerberos_kinit_password_ext(const char *principal, if (renew_till_time) { *renew_till_time = (time_t) my_creds.times.renew_till; } - - krb5_cc_close(ctx, cc); - smb_krb5_free_addresses(ctx, addr); + out: krb5_free_cred_contents(ctx, &my_creds); - krb5_free_principal(ctx, me); - krb5_free_context(ctx); - - return 0; + if (me) { + krb5_free_principal(ctx, me); + } + if (addr) { + smb_krb5_free_addresses(ctx, addr); + } + if (opt) { + smb_krb5_get_init_creds_opt_free(ctx, opt); + } + if (cc) { + krb5_cc_close(ctx, cc); + } + if (ctx) { + krb5_free_context(ctx); + } + return code; } -- cgit From 116c1532e7e8c398a1b22253a361bd88b729fb0f Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 4 May 2007 09:55:40 +0000 Subject: r22664: When we have krb5_get_init_creds_opt_get_error() then try to get the NTSTATUS codes directly out of the krb5_error edata. Guenther (This used to be commit dcd902f24a59288bbb7400d59c0afc0c8303ed69) --- source3/libads/kerberos.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 72ff2cbdab..dc3d11a60c 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -55,6 +55,127 @@ kerb_prompter(krb5_context ctx, void *data, return 0; } +static BOOL smb_krb5_err_io_nstatus(TALLOC_CTX *mem_ctx, + DATA_BLOB *edata_blob, + KRB5_EDATA_NTSTATUS *edata) +{ + BOOL ret = False; + prs_struct ps; + + if (!mem_ctx || !edata_blob || !edata) + return False; + + if (!prs_init(&ps, edata_blob->length, mem_ctx, UNMARSHALL)) + return False; + + if (!prs_copy_data_in(&ps, (char *)edata_blob->data, edata_blob->length)) + goto out; + + prs_set_offset(&ps, 0); + + if (!prs_ntstatus("ntstatus", &ps, 1, &edata->ntstatus)) + goto out; + + if (!prs_uint32("unknown1", &ps, 1, &edata->unknown1)) + goto out; + + if (!prs_uint32("unknown2", &ps, 1, &edata->unknown2)) /* only seen 00000001 here */ + goto out; + + ret = True; + out: + prs_mem_free(&ps); + + return ret; +} + + static BOOL smb_krb5_get_ntstatus_from_krb5_error(krb5_error *error, + NTSTATUS *nt_status) +{ + DATA_BLOB edata; + DATA_BLOB unwrapped_edata; + TALLOC_CTX *mem_ctx; + KRB5_EDATA_NTSTATUS parsed_edata; + +#ifdef HAVE_E_DATA_POINTER_IN_KRB5_ERROR + edata = data_blob(error->e_data->data, error->e_data->length); +#else + edata = data_blob(error->e_data.data, error->e_data.length); +#endif /* HAVE_E_DATA_POINTER_IN_KRB5_ERROR */ + +#ifdef DEVELOPER + dump_data(10, edata.data, edata.length); +#endif /* DEVELOPER */ + + mem_ctx = talloc_init("smb_krb5_get_ntstatus_from_krb5_error"); + if (mem_ctx == NULL) { + data_blob_free(&edata); + return False; + } + + if (!unwrap_edata_ntstatus(mem_ctx, &edata, &unwrapped_edata)) { + data_blob_free(&edata); + TALLOC_FREE(mem_ctx); + return False; + } + + data_blob_free(&edata); + + if (!smb_krb5_err_io_nstatus(mem_ctx, &unwrapped_edata, &parsed_edata)) { + data_blob_free(&unwrapped_edata); + TALLOC_FREE(mem_ctx); + return False; + } + + data_blob_free(&unwrapped_edata); + + if (nt_status) { + *nt_status = parsed_edata.ntstatus; + } + + TALLOC_FREE(mem_ctx); + + return True; +} + + static BOOL smb_krb5_get_ntstatus_from_krb5_error_init_creds_opt(krb5_context ctx, + krb5_get_init_creds_opt *opt, + NTSTATUS *nt_status) +{ + BOOL ret = False; + krb5_error *error = NULL; + +#ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_GET_ERROR + ret = krb5_get_init_creds_opt_get_error(ctx, opt, &error); + if (ret) { + DEBUG(1,("krb5_get_init_creds_opt_get_error gave: %s\n", + error_message(ret))); + return False; + } +#endif /* HAVE_KRB5_GET_INIT_CREDS_OPT_GET_ERROR */ + + if (!error) { + DEBUG(1,("no krb5_error\n")); + return False; + } + +#ifdef HAVE_E_DATA_POINTER_IN_KRB5_ERROR + if (!error->e_data) { +#else + if (error->e_data.data == NULL) { +#endif /* HAVE_E_DATA_POINTER_IN_KRB5_ERROR */ + DEBUG(1,("no edata in krb5_error\n")); + krb5_free_error(ctx, error); + return False; + } + + ret = smb_krb5_get_ntstatus_from_krb5_error(error, nt_status); + + krb5_free_error(ctx, error); + + return ret; +} + /* simulate a kinit, putting the tgt in the given cache location. If cache_name == NULL place in default cache location. -- cgit From e468268335dd797c540dbd278541340d8c01a7d1 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 4 May 2007 10:21:39 +0000 Subject: r22666: Expand kerberos_kinit_password_ext() to return NTSTATUS codes and make winbindd's kerberized pam_auth use that. Guenther (This used to be commit 0f436eab5b2e5891c341c27cb22db52a72bf1af7) --- source3/libads/kerberos.c | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index dc3d11a60c..c721b56385 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -189,7 +189,8 @@ int kerberos_kinit_password_ext(const char *principal, const char *cache_name, BOOL request_pac, BOOL add_netbios_addr, - time_t renewable_time) + time_t renewable_time, + NTSTATUS *ntstatus) { krb5_context ctx = NULL; krb5_error_code code = 0; @@ -267,6 +268,29 @@ int kerberos_kinit_password_ext(const char *principal, *renew_till_time = (time_t) my_creds.times.renew_till; } out: + if (ntstatus) { + + NTSTATUS status; + + /* fast path */ + if (code == 0) { + *ntstatus = NT_STATUS_OK; + goto cleanup; + } + + /* try to get ntstatus code out of krb5_error when we have it + * inside the krb5_get_init_creds_opt - gd */ + + if (opt && smb_krb5_get_ntstatus_from_krb5_error_init_creds_opt(ctx, opt, &status)) { + *ntstatus = status; + goto cleanup; + } + + /* fall back to self-made-mapping */ + *ntstatus = krb5_to_nt_status(code); + } + + cleanup: krb5_free_cred_contents(ctx, &my_creds); if (me) { krb5_free_principal(ctx, me); @@ -321,7 +345,8 @@ int ads_kinit_password(ADS_STRUCT *ads) } ret = kerberos_kinit_password_ext(s, ads->auth.password, ads->auth.time_offset, - &ads->auth.tgt_expire, NULL, NULL, False, False, ads->auth.renewable); + &ads->auth.tgt_expire, NULL, NULL, False, False, ads->auth.renewable, + NULL); if (ret) { DEBUG(0,("kerberos_kinit_password %s failed: %s\n", @@ -580,7 +605,8 @@ int kerberos_kinit_password(const char *principal, cache_name, False, False, - 0); + 0, + NULL); } /************************************************************************ -- cgit From 8ff276fcb02111664c727178296590d97eb09319 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Sun, 6 May 2007 18:56:43 +0000 Subject: r22701: Fix the krb5_nt_status error table and add the "no DCs found" mapping (This used to be commit 2ab617fbbffbd6bf98ee02150f62b87a2610531f) --- source3/libads/krb5_errs.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/krb5_errs.c b/source3/libads/krb5_errs.c index c153bee96e..8216fefb64 100644 --- a/source3/libads/krb5_errs.c +++ b/source3/libads/krb5_errs.c @@ -58,10 +58,12 @@ static const struct { #endif {KRB5_CC_NOTFOUND, NT_STATUS_NO_SUCH_FILE}, {KRB5_FCC_NOFILE, NT_STATUS_NO_SUCH_FILE}, - {KRB5KDC_ERR_NONE, NT_STATUS_OK}, {KRB5_RC_MALLOC, NT_STATUS_NO_MEMORY}, {ENOMEM, NT_STATUS_NO_MEMORY}, - {0, NT_STATUS_OK} + {KRB5_REALM_CANT_RESOLVE, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND}, + + /* Must be last entry */ + {KRB5KDC_ERR_NONE, NT_STATUS_OK} }; static const struct { -- cgit From 89fd4444aff2c858605f71d46715e3b366e82749 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Sun, 6 May 2007 21:06:55 +0000 Subject: r22714: Prevent DNS lookup storms when the DNS servers are unreachable. Helps when transitioning from offline to online mode. Note that this is a quick hack and a better solution would be to start the DNS server's state between processes (similar to the namecache entries). (This used to be commit 4f05c6fe26f4abd7ca71eac339fee2ef5e254369) --- source3/libads/dns.c | 49 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 9 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/dns.c b/source3/libads/dns.c index f16cea2555..e0e696c99c 100644 --- a/source3/libads/dns.c +++ b/source3/libads/dns.c @@ -270,45 +270,76 @@ static int dnssrvcmp( struct dns_rr_srv *a, struct dns_rr_srv *b ) Simple wrapper for a DNS query *********************************************************************/ +#define DNS_FAILED_WAITTIME 30 + static NTSTATUS dns_send_req( TALLOC_CTX *ctx, const char *name, int q_type, uint8 **buf, int *resp_length ) { uint8 *buffer = NULL; size_t buf_len; int resp_len = NS_PACKETSZ; - + static time_t last_dns_check = 0; + static NTSTATUS last_dns_status = NT_STATUS_OK; + time_t now = time(NULL); + + /* Try to prevent bursts of DNS lookups if the server is down */ + + /* Protect against large clock changes */ + + if ( last_dns_check > now ) + last_dns_check = 0; + + /* IF we had a DNS timeout or a bad server and we are still + in the 30 second cache window, just return the previous + status and save the network timeout. */ + + if ( (NT_STATUS_EQUAL(last_dns_status,NT_STATUS_IO_TIMEOUT) || + NT_STATUS_EQUAL(last_dns_status,NT_STATUS_CONNECTION_REFUSED)) && + (last_dns_check+DNS_FAILED_WAITTIME) > now ) + { + DEBUG(10,("last_dns_check: Returning cached status (%s)\n", + nt_errstr(last_dns_status) )); + return last_dns_status; + } + + /* Send the Query */ do { if ( buffer ) TALLOC_FREE( buffer ); buf_len = resp_len * sizeof(uint8); - if (buf_len) { + if (buf_len) { if ( (buffer = TALLOC_ARRAY(ctx, uint8, buf_len)) == NULL ) { DEBUG(0,("ads_dns_lookup_srv: talloc() failed!\n")); - return NT_STATUS_NO_MEMORY; + last_dns_status = NT_STATUS_NO_MEMORY; + last_dns_check = time(NULL); + return last_dns_status; } - } else { - buffer = NULL; } if ( (resp_len = res_query(name, C_IN, q_type, buffer, buf_len)) < 0 ) { DEBUG(3,("ads_dns_lookup_srv: Failed to resolve %s (%s)\n", name, strerror(errno))); TALLOC_FREE( buffer ); + last_dns_status = NT_STATUS_UNSUCCESSFUL; + if (errno == ETIMEDOUT) { - return NT_STATUS_IO_TIMEOUT; + last_dns_status = NT_STATUS_IO_TIMEOUT; } if (errno == ECONNREFUSED) { - return NT_STATUS_CONNECTION_REFUSED; + last_dns_status = NT_STATUS_CONNECTION_REFUSED; } - return NT_STATUS_UNSUCCESSFUL; + last_dns_check = time(NULL); + return last_dns_status; } } while ( buf_len < resp_len && resp_len < MAX_DNS_PACKET_SIZE ); *buf = buffer; *resp_length = resp_len; - return NT_STATUS_OK; + last_dns_check = time(NULL); + last_dns_status = NT_STATUS_OK; + return last_dns_status; } /********************************************************************* -- cgit From 3eca3af1bcd92e575b8c5d1034efd8d516df5e6c Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Sun, 6 May 2007 21:45:53 +0000 Subject: r22728: Patch from Danilo Almeida : When asked to create a machine account in an OU as part of "net ads join" and the account already exists in another OU, simply move the machine object to the requested OU. (This used to be commit 3004cc6e593e6659a618de66f659f579e71c07f7) --- source3/libads/ldap.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 5a34385c32..af4347c147 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1688,6 +1688,76 @@ done: return ret; } +/** + * move a machine account to another OU on the ADS server + * @param ads - An intialized ADS_STRUCT + * @param machine_name - the NetBIOS machine name of this account. + * @param org_unit - The LDAP path in which to place this account + * @param moved - whether we moved the machine account (optional) + * @return 0 upon success, or non-zero otherwise +**/ + +ADS_STATUS ads_move_machine_acct(ADS_STRUCT *ads, const char *machine_name, + const char *org_unit, BOOL *moved) +{ + ADS_STATUS rc; + int ldap_status; + LDAPMessage *res = NULL; + char *filter = NULL; + char *computer_dn = NULL; + char *parent_dn; + char *computer_rdn = NULL; + BOOL need_move = False; + + if (asprintf(&filter, "(samAccountName=%s$)", machine_name) == -1) { + rc = ADS_ERROR(LDAP_NO_MEMORY); + goto done; + } + + /* Find pre-existing machine */ + rc = ads_search(ads, &res, filter, NULL); + if (!ADS_ERR_OK(rc)) { + goto done; + } + + computer_dn = ads_get_dn(ads, res); + if (!computer_dn) { + rc = ADS_ERROR(LDAP_NO_MEMORY); + goto done; + } + + parent_dn = ads_parent_dn(computer_dn); + if (strequal(parent_dn, org_unit)) { + goto done; + } + + need_move = True; + + if (asprintf(&computer_rdn, "CN=%s", machine_name) == -1) { + rc = ADS_ERROR(LDAP_NO_MEMORY); + goto done; + } + + ldap_status = ldap_rename2_s(ads->ld, computer_dn, computer_rdn, org_unit, 1); + rc = ADS_ERROR(ldap_status); + +done: + ads_msgfree(ads, res); + SAFE_FREE(filter); + SAFE_FREE(computer_dn); + SAFE_FREE(computer_rdn); + + if (!ADS_ERR_OK(rc)) { + need_move = False; + } + + if (moved) { + *moved = need_move; + } + + return rc; +} + /* dump a binary result from ldap */ -- cgit From 9c170fce2632e76bda6bb9a644777c978785cff1 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 11 May 2007 12:52:48 +0000 Subject: r22797: We are only interested in the DACL of the security descriptor, so search with the SD_FLAGS control. Guenther (This used to be commit 648df57e53ddabe74052e816b8eba95180736208) --- source3/libads/ldap.c | 54 +++++++++++++++++++++++++++++---------------- source3/libads/ldap_utils.c | 16 ++++++++++++++ 2 files changed, 51 insertions(+), 19 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index af4347c147..ff416b0085 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -570,11 +570,11 @@ static ADS_STATUS ads_do_paged_search_args(ADS_STRUCT *ads, { int rc, i, version; char *utf8_expr, *utf8_path, **search_attrs; - LDAPControl PagedResults, NoReferrals, ExtendedDn, *controls[4], **rcontrols; + LDAPControl PagedResults, NoReferrals, ExternalCtrl, *controls[4], **rcontrols; BerElement *cookie_be = NULL; struct berval *cookie_bv= NULL; - BerElement *extdn_be = NULL; - struct berval *extdn_bv= NULL; + BerElement *ext_be = NULL; + struct berval *ext_bv= NULL; TALLOC_CTX *ctx; ads_control *external_control = (ads_control *) args; @@ -604,7 +604,6 @@ static ADS_STATUS ads_do_paged_search_args(ADS_STRUCT *ads, } } - /* Paged results only available on ldap v3 or later */ ldap_get_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); if (version < LDAP_VERSION3) { @@ -631,40 +630,42 @@ static ADS_STATUS ads_do_paged_search_args(ADS_STRUCT *ads, NoReferrals.ldctl_value.bv_len = 0; NoReferrals.ldctl_value.bv_val = CONST_DISCARD(char *, ""); - if (external_control && strequal(external_control->control, ADS_EXTENDED_DN_OID)) { + if (external_control && + (strequal(external_control->control, ADS_EXTENDED_DN_OID) || + strequal(external_control->control, ADS_SD_FLAGS_OID))) { - ExtendedDn.ldctl_oid = CONST_DISCARD(char *, external_control->control); - ExtendedDn.ldctl_iscritical = (char) external_control->critical; + ExternalCtrl.ldctl_oid = CONST_DISCARD(char *, external_control->control); + ExternalCtrl.ldctl_iscritical = (char) external_control->critical; /* win2k does not accept a ldctl_value beeing passed in */ if (external_control->val != 0) { - if ((extdn_be = ber_alloc_t(LBER_USE_DER)) == NULL ) { + if ((ext_be = ber_alloc_t(LBER_USE_DER)) == NULL ) { rc = LDAP_NO_MEMORY; goto done; } - if ((ber_printf(extdn_be, "{i}", (ber_int_t) external_control->val)) == -1) { + if ((ber_printf(ext_be, "{i}", (ber_int_t) external_control->val)) == -1) { rc = LDAP_NO_MEMORY; goto done; } - if ((ber_flatten(extdn_be, &extdn_bv)) == -1) { + if ((ber_flatten(ext_be, &extdn_bv)) == -1) { rc = LDAP_NO_MEMORY; goto done; } - ExtendedDn.ldctl_value.bv_len = extdn_bv->bv_len; - ExtendedDn.ldctl_value.bv_val = extdn_bv->bv_val; + ExternalCtrl.ldctl_value.bv_len = ext_bv->bv_len; + ExternalCtrl.ldctl_value.bv_val = ext_bv->bv_val; } else { - ExtendedDn.ldctl_value.bv_len = 0; - ExtendedDn.ldctl_value.bv_val = NULL; + ExternalCtrl.ldctl_value.bv_len = 0; + ExternalCtrl.ldctl_value.bv_val = NULL; } controls[0] = &NoReferrals; controls[1] = &PagedResults; - controls[2] = &ExtendedDn; + controls[2] = &ExternalCtrl; controls[3] = NULL; } else { @@ -725,12 +726,12 @@ static ADS_STATUS ads_do_paged_search_args(ADS_STRUCT *ads, done: talloc_destroy(ctx); - if (extdn_be) { - ber_free(extdn_be, 1); + if (ext_be) { + ber_free(ext_be, 1); } - if (extdn_bv) { - ber_bvfree(extdn_bv); + if (ext_bv) { + ber_bvfree(ext_bv); } /* if/when we decide to utf8-encode attrs, take out this next line */ @@ -810,6 +811,21 @@ static ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, return ads_do_search_all_args(ads, bind_path, scope, expr, attrs, NULL, res); } + ADS_STATUS ads_do_search_all_sd_flags(ADS_STRUCT *ads, const char *bind_path, + int scope, const char *expr, + const char **attrs, uint32 sd_flags, + LDAPMessage **res) +{ + ads_control args; + + args.control = ADS_SD_FLAGS_OID; + args.val = sd_flags; + args.critical = True; + + return ads_do_search_all_args(ads, bind_path, scope, expr, attrs, &args, res); +} + + /** * Run a function on all results for a search. Uses ads_do_paged_search() and * runs the function as each page is returned, using ads_process_results() diff --git a/source3/libads/ldap_utils.c b/source3/libads/ldap_utils.c index 383b652f97..6417e92e92 100644 --- a/source3/libads/ldap_utils.c +++ b/source3/libads/ldap_utils.c @@ -4,6 +4,7 @@ Some Helpful wrappers on LDAP Copyright (C) Andrew Tridgell 2001 + Copyright (C) Guenther Deschner 2006,2007 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -185,6 +186,21 @@ static ADS_STATUS ads_do_search_retry_internal(ADS_STRUCT *ads, const char *bind "(objectclass=*)", &args, attrs[0], strings, num_strings); +} + + ADS_STATUS ads_search_retry_dn_sd_flags(ADS_STRUCT *ads, LDAPMessage **res, + uint32 sd_flags, + const char *dn, + const char **attrs) +{ + ads_control args; + + args.control = ADS_SD_FLAGS_OID; + args.val = sd_flags; + args.critical = True; + + return ads_do_search_retry_args(ads, dn, LDAP_SCOPE_BASE, + "(objectclass=*)", attrs, &args, res); } ADS_STATUS ads_search_retry_sid(ADS_STRUCT *ads, LDAPMessage **res, -- cgit From 46c5da2fd668ceecf0009374b508f3cf0d1c3e3e Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 11 May 2007 12:59:16 +0000 Subject: r22798: Add the "apply group policy" access bit (as seen in type 0x05 ALLOWED OBJECT ACEs). Guenther (This used to be commit e138cbc876e50ae25cb15c5109a42bc8b800c1ba) --- source3/libads/disp_sec.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/disp_sec.c b/source3/libads/disp_sec.c index a768ba08f3..1e62eb8551 100644 --- a/source3/libads/disp_sec.c +++ b/source3/libads/disp_sec.c @@ -46,6 +46,9 @@ static struct perm_mask_str { {SEC_RIGHTS_CHANGE_PASSWD, "[Change Password]"}, {SEC_RIGHTS_RESET_PASSWD, "[Reset Password]"}, + + {SEC_RIGHTS_APPLY_GROUP_POLICY, "[Apply Group Policy]"}, + {0, 0} }; @@ -66,7 +69,7 @@ static void ads_disp_perms(uint32 type) if (type & (1 << i)) { for (j = 1; perms[j].str; j ++) { if (perms[j].mask == (((unsigned) 1) << i)) { - printf("\n\t%s", perms[j].str); + printf("\n\t%s (0x%08x)", perms[j].str, perms[j].mask); } } type &= ~(1 << i); -- cgit From 75a0171857001bda9ac321e5f02dce516343f0ae Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 11 May 2007 13:19:49 +0000 Subject: r22799: Fix the build. Guenther (This used to be commit 6e911c442bf9b076f43f99576f9b588df2c39233) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index ff416b0085..48be73230e 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -650,7 +650,7 @@ static ADS_STATUS ads_do_paged_search_args(ADS_STRUCT *ads, rc = LDAP_NO_MEMORY; goto done; } - if ((ber_flatten(ext_be, &extdn_bv)) == -1) { + if ((ber_flatten(ext_be, &ext_bv)) == -1) { rc = LDAP_NO_MEMORY; goto done; } -- cgit From 83564b43e3b8194b89e0fb8547a968e4f2ff022b Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 11 May 2007 13:33:37 +0000 Subject: r22800: Add GPO_SID_TOKEN and an LDAP function to get tokensids from the tokenGroup attribute. Guenther (This used to be commit e4e8f840605dfdf92ca60cc8fc6a4c85336565fb) --- source3/libads/ldap.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 48be73230e..f5f273d3f2 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -3196,4 +3196,108 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) return status; } +/** + * pull all token-sids from an LDAP dn + * @param ads connection to ads server + * @param mem_ctx TALLOC_CTX for allocating sid array + * @param dn of LDAP object + * @param user_sid pointer to DOM_SID (objectSid) + * @param primary_group_sid pointer to DOM_SID (self composed) + * @param sids pointer to sid array to allocate + * @param num_sids counter of SIDs pulled + * @return status of token query + **/ + ADS_STATUS ads_get_tokensids(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + const char *dn, + DOM_SID *user_sid, + DOM_SID *primary_group_sid, + DOM_SID **sids, + size_t *num_sids) +{ + ADS_STATUS status; + LDAPMessage *res = NULL; + int count = 0; + size_t tmp_num_sids; + DOM_SID *tmp_sids; + DOM_SID tmp_user_sid; + DOM_SID tmp_primary_group_sid; + uint32 pgid; + const char *attrs[] = { + "objectSid", + "tokenGroups", + "primaryGroupID", + NULL + }; + + status = ads_search_retry_dn(ads, &res, dn, attrs); + if (!ADS_ERR_OK(status)) { + return status; + } + + count = ads_count_replies(ads, res); + if (count != 1) { + ads_msgfree(ads, res); + return ADS_ERROR_LDAP(LDAP_NO_SUCH_OBJECT); + } + + if (!ads_pull_sid(ads, res, "objectSid", &tmp_user_sid)) { + ads_msgfree(ads, res); + return ADS_ERROR_LDAP(LDAP_NO_MEMORY); + } + + if (!ads_pull_uint32(ads, res, "primaryGroupID", &pgid)) { + ads_msgfree(ads, res); + return ADS_ERROR_LDAP(LDAP_NO_MEMORY); + } + + { + /* hack to compose the primary group sid without knowing the + * domsid */ + + DOM_SID domsid; + uint32 dummy_rid; + + sid_copy(&domsid, &tmp_user_sid); + + if (!sid_split_rid(&domsid, &dummy_rid)) { + ads_msgfree(ads, res); + return ADS_ERROR_LDAP(LDAP_NO_MEMORY); + } + + if (!sid_compose(&tmp_primary_group_sid, &domsid, pgid)) { + ads_msgfree(ads, res); + return ADS_ERROR_LDAP(LDAP_NO_MEMORY); + } + } + + tmp_num_sids = ads_pull_sids(ads, mem_ctx, res, "tokenGroups", &tmp_sids); + + if (tmp_num_sids == 0 || !tmp_sids) { + ads_msgfree(ads, res); + return ADS_ERROR_LDAP(LDAP_NO_MEMORY); + } + + if (num_sids) { + *num_sids = tmp_num_sids; + } + + if (sids) { + *sids = tmp_sids; + } + + if (user_sid) { + *user_sid = tmp_user_sid; + } + + if (primary_group_sid) { + *primary_group_sid = tmp_primary_group_sid; + } + + DEBUG(10,("ads_get_tokensids: returned %d sids\n", (int)tmp_num_sids + 2)); + + ads_msgfree(ads, res); + return ADS_ERROR_LDAP(LDAP_SUCCESS); +} + #endif -- cgit From b4a7b7a8889737e2891fc1176feabd4ce47f2737 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 14 May 2007 12:16:20 +0000 Subject: r22844: Introduce const DATA_BLOB data_blob_null = { NULL, 0, NULL }; and replace all data_blob(NULL, 0) calls. (This used to be commit 3d3d61687ef00181f4f04e001d42181d93ac931e) --- source3/libads/cldap.c | 8 ++++---- source3/libads/kerberos_verify.c | 4 ++-- source3/libads/krb5_setpw.c | 2 +- source3/libads/sasl.c | 18 +++++++++--------- 4 files changed, 16 insertions(+), 16 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/cldap.c b/source3/libads/cldap.c index 3cb98c59c5..227bbc2a0a 100644 --- a/source3/libads/cldap.c +++ b/source3/libads/cldap.c @@ -187,10 +187,10 @@ static int recv_cldap_netlogon(int sock, struct cldap_netlogon_reply *reply) { int ret; ASN1_DATA data; - DATA_BLOB blob = data_blob(NULL, 0); - DATA_BLOB os1 = data_blob(NULL, 0); - DATA_BLOB os2 = data_blob(NULL, 0); - DATA_BLOB os3 = data_blob(NULL, 0); + 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); diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 0ec03ef4bf..ca36e6e425 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -333,8 +333,8 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, *principal = NULL; *pac_data = NULL; - *ap_rep = data_blob(NULL,0); - *session_key = data_blob(NULL,0); + *ap_rep = data_blob_null; + *session_key = data_blob_null; initialize_krb5_error_table(); ret = krb5_init_context(&context); diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index c7a4b982db..4aab09c9f4 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -88,7 +88,7 @@ static DATA_BLOB encode_krb5_setpw(const char *principal, const char *password) realm = c; } else { /* We must have a realm component. */ - return data_blob(NULL, 0); + return data_blob_null; } memset(&req, 0, sizeof(req)); diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 2fc66bd929..f1f0861535 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -28,10 +28,10 @@ */ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) { - DATA_BLOB msg1 = data_blob(NULL, 0); - DATA_BLOB blob = data_blob(NULL, 0); - DATA_BLOB blob_in = data_blob(NULL, 0); - DATA_BLOB blob_out = data_blob(NULL, 0); + DATA_BLOB msg1 = data_blob_null; + DATA_BLOB blob = data_blob_null; + DATA_BLOB blob_in = data_blob_null; + DATA_BLOB blob_out = data_blob_null; struct berval cred, *scred = NULL; int rc; NTSTATUS nt_status; @@ -54,7 +54,7 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) return ADS_ERROR_NT(nt_status); } - blob_in = data_blob(NULL, 0); + blob_in = data_blob_null; do { nt_status = ntlmssp_update(ntlmssp_state, @@ -90,7 +90,7 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) blob = data_blob(scred->bv_val, scred->bv_len); ber_bvfree(scred); } else { - blob = data_blob(NULL, 0); + blob = data_blob_null; } } else { @@ -102,7 +102,7 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) if ((turn == 1) && (rc == LDAP_SASL_BIND_IN_PROGRESS)) { - DATA_BLOB tmp_blob = data_blob(NULL, 0); + DATA_BLOB tmp_blob = data_blob_null; /* the server might give us back two challenges */ if (!spnego_parse_challenge(blob, &blob_in, &tmp_blob)) { @@ -142,9 +142,9 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) */ static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *principal) { - DATA_BLOB blob = data_blob(NULL, 0); + DATA_BLOB blob = data_blob_null; struct berval cred, *scred = NULL; - DATA_BLOB session_key = data_blob(NULL, 0); + DATA_BLOB session_key = data_blob_null; int rc; rc = spnego_gen_negTokenTarg(principal, ads->auth.time_offset, &blob, &session_key, 0, -- cgit From 2753d30cbea6cc6689cda17182caff20d65c6f6c Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 15 May 2007 10:47:40 +0000 Subject: r22893: Use ldap_rename_s instead of deprecated ldap_rename2_s. This fixes the build on solaris (host sun9). And hopefully doesn't break any other builds... :-) If it does, we need some configure magic. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Thanks to Björn Jacke . (This used to be commit a43775ab36aa3d36108e1b5860bbee6c47e9b1b4) --- source3/libads/ldap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index f5f273d3f2..5b87017d84 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1754,7 +1754,8 @@ ADS_STATUS ads_move_machine_acct(ADS_STRUCT *ads, const char *machine_name, goto done; } - ldap_status = ldap_rename2_s(ads->ld, computer_dn, computer_rdn, org_unit, 1); + ldap_status = ldap_rename_s(ads->ld, computer_dn, computer_rdn, + org_unit, 1, NULL, NULL); rc = ADS_ERROR(ldap_status); done: -- cgit From 71ee55f98d87ff70e5feb0d2b280e9c71f7b9b6a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 22 May 2007 20:20:01 +0000 Subject: r23080: Fix bug #4637 - we hads missed some cases where we were calling PRS_ALLOC_MEM with zero count. Jeremy. (This used to be commit 9a10736e6fa276ca4b0726fbb7baf0daafbdc46d) --- source3/libads/authdata.c | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c index 71294941a6..8e951dde80 100644 --- a/source3/libads/authdata.c +++ b/source3/libads/authdata.c @@ -120,10 +120,14 @@ static BOOL pac_io_krb_sid_and_attr_array(const char *desc, return False; if (UNMARSHALLING(ps)) { - array->krb_sid_and_attrs = PRS_ALLOC_MEM(ps, KRB_SID_AND_ATTRS, num); - if (!array->krb_sid_and_attrs) { - DEBUG(3, ("No memory available\n")); - return False; + if (num) { + array->krb_sid_and_attrs = PRS_ALLOC_MEM(ps, KRB_SID_AND_ATTRS, num); + if (!array->krb_sid_and_attrs) { + DEBUG(3, ("No memory available\n")); + return False; + } + } else { + array->krb_sid_and_attrs = NULL; } } @@ -184,10 +188,14 @@ static BOOL pac_io_group_membership_array(const char *desc, return False; if (UNMARSHALLING(ps)) { - array->group_membership = PRS_ALLOC_MEM(ps, GROUP_MEMBERSHIP, num); - if (!array->group_membership) { - DEBUG(3, ("No memory available\n")); - return False; + if (num) { + array->group_membership = PRS_ALLOC_MEM(ps, GROUP_MEMBERSHIP, num); + if (!array->group_membership) { + DEBUG(3, ("No memory available\n")); + return False; + } + } else { + array->group_membership = NULL; } } @@ -456,10 +464,14 @@ static BOOL pac_io_pac_signature_data(const char *desc, return False; if (UNMARSHALLING(ps) && length) { - data->signature.buffer = PRS_ALLOC_MEM(ps, uint8, siglen); - if (!data->signature.buffer) { - DEBUG(3, ("No memory available\n")); - return False; + if (siglen) { + data->signature.buffer = PRS_ALLOC_MEM(ps, uint8, siglen); + if (!data->signature.buffer) { + DEBUG(3, ("No memory available\n")); + return False; + } + } else { + data->signature.buffer = NULL; } } -- cgit From ad5ff1b8090b225b7ac6d5b7ec08d9f70633db5e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 25 May 2007 22:04:03 +0000 Subject: r23147: Patch #4566 from jacob berkman . Pass password data to krb5_prompter. Jeremy. (This used to be commit 232fc5d69d44404df13f6516864352f9a5721552) --- source3/libads/kerberos.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index c721b56385..841674bea5 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -248,7 +248,8 @@ int kerberos_kinit_password_ext(const char *principal, } if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, CONST_DISCARD(char *,password), - kerb_prompter, NULL, 0, NULL, opt))) { + kerb_prompter, CONST_DISCARD(char *,password), + 0, NULL, opt))) { goto out; } -- cgit From 3272b1dd602196b2105afda1f9979a8f9596d71e Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 30 May 2007 21:55:49 +0000 Subject: r23251: whoops! Fix compile error (This used to be commit 22a3ea40ac69fa3722abf28db845ab284a65ad97) --- source3/libads/authdata.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c index 8e951dde80..9dfb9cba09 100644 --- a/source3/libads/authdata.c +++ b/source3/libads/authdata.c @@ -451,10 +451,11 @@ static BOOL pac_io_pac_signature_data(const char *desc, PAC_SIGNATURE_DATA *data, uint32 length, prs_struct *ps, int depth) { - uint32 siglen = length - sizeof(uint32); + uint32 siglen = 0; + prs_debug(ps, depth, desc, "pac_io_pac_signature_data"); depth++; - + if (data == NULL) return False; @@ -463,6 +464,9 @@ static BOOL pac_io_pac_signature_data(const char *desc, if (!prs_uint32("type", ps, depth, &data->type)) return False; + if ( length > sizeof(uint32) ) + siglen = length - sizeof(uint32); + if (UNMARSHALLING(ps) && length) { if (siglen) { data->signature.buffer = PRS_ALLOC_MEM(ps, uint8, siglen); -- cgit From 4caefdf348857577343075ae647e29a0ac904ae0 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 13 Jun 2007 20:49:20 +0000 Subject: r23474: Here's a small patch that disables the libkrb5.so replay cache when verifying a ticket from winbindd_pam.c. I've found during multiple, fast, automated SSH logins (such as from a cron script) that the replay cache in MIT's krb5 lib will occasionally fail the krb5_rd_req() as a replay attack. There seems to be a small window during which the MIT krb5 libs could reproduce identical time stamps for ctime and cusec in the authenticator since Unix systems only give back milli-seconds rather than the micro-seconds needed by the authenticator. Checked against MIT 1.5.1. Have not researched how Heimdal does it. My thinking is that if someone can spoof the KDC and TDS services we are pretty hopeless anyways. (This used to be commit cbd33da9f78373e29729325bbab1ae9040712b11) --- source3/libads/kerberos_verify.c | 102 ++++++++++++++++++++++++--------------- 1 file changed, 63 insertions(+), 39 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index ca36e6e425..ecd0f0869c 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -214,7 +214,14 @@ static krb5_error_code ads_secrets_verify_ticket(krb5_context context, BOOL auth_ok = False; char *password_s = NULL; krb5_data password; - krb5_enctype enctypes[4] = { ENCTYPE_DES_CBC_CRC, ENCTYPE_DES_CBC_MD5, 0, 0 }; + krb5_enctype enctypes[] = { +#if defined(ENCTYPE_ARCFOUR_HMAC) + ENCTYPE_ARCFOUR_HMAC, +#endif + ENCTYPE_DES_CBC_CRC, + ENCTYPE_DES_CBC_MD5, + ENCTYPE_NULL + }; krb5_data packet; int i; @@ -222,9 +229,6 @@ static krb5_error_code ads_secrets_verify_ticket(krb5_context context, *keyblock = NULL; *perr = 0; -#if defined(ENCTYPE_ARCFOUR_HMAC) - enctypes[2] = ENCTYPE_ARCFOUR_HMAC; -#endif if (!secrets_init()) { DEBUG(1,("ads_secrets_verify_ticket: secrets_init failed\n")); @@ -307,7 +311,8 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, char **principal, PAC_DATA **pac_data, DATA_BLOB *ap_rep, - DATA_BLOB *session_key) + DATA_BLOB *session_key, + BOOL use_replay_cache) { NTSTATUS sret = NT_STATUS_LOGON_FAILURE; NTSTATUS pac_ret; @@ -320,7 +325,7 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, krb5_keyblock *keyblock = NULL; time_t authtime; krb5_error_code ret = 0; - + krb5_int32 flags = 0; krb5_principal host_princ = NULL; krb5_const_principal client_principal = NULL; char *host_princ_s = NULL; @@ -363,6 +368,13 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, goto out; } + krb5_auth_con_getflags( context, auth_context, &flags ); + if ( !use_replay_cache ) { + /* Disable default use of a replay cache */ + flags &= ~KRB5_AUTH_CONTEXT_DO_TIME; + krb5_auth_con_setflags( context, auth_context, flags ); + } + asprintf(&host_princ_s, "%s$", global_myname()); if (!host_princ_s) { goto out; @@ -377,50 +389,62 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, } - /* Lock a mutex surrounding the replay as there is no locking in the MIT krb5 - * code surrounding the replay cache... */ + if ( use_replay_cache ) { + + /* Lock a mutex surrounding the replay as there is no + locking in the MIT krb5 code surrounding the replay + cache... */ - if (!grab_server_mutex("replay cache mutex")) { - DEBUG(1,("ads_verify_ticket: unable to protect replay cache with mutex.\n")); - ret = KRB5_CC_IO; - goto out; - } + if (!grab_server_mutex("replay cache mutex")) { + DEBUG(1,("ads_verify_ticket: unable to protect " + "replay cache with mutex.\n")); + ret = KRB5_CC_IO; + goto out; + } - got_replay_mutex = True; + got_replay_mutex = True; - /* - * JRA. We must set the rcache here. This will prevent replay attacks. - */ + /* JRA. We must set the rcache here. This will prevent + replay attacks. */ + + ret = krb5_get_server_rcache(context, + krb5_princ_component(context, host_princ, 0), + &rcache); + if (ret) { + DEBUG(1,("ads_verify_ticket: krb5_get_server_rcache " + "failed (%s)\n", error_message(ret))); + goto out; + } - ret = krb5_get_server_rcache(context, krb5_princ_component(context, host_princ, 0), &rcache); - if (ret) { - DEBUG(1,("ads_verify_ticket: krb5_get_server_rcache failed (%s)\n", error_message(ret))); - goto out; + ret = krb5_auth_con_setrcache(context, auth_context, rcache); + if (ret) { + DEBUG(1,("ads_verify_ticket: krb5_auth_con_setrcache " + "failed (%s)\n", error_message(ret))); + goto out; + } } - ret = krb5_auth_con_setrcache(context, auth_context, rcache); - if (ret) { - DEBUG(1,("ads_verify_ticket: krb5_auth_con_setrcache failed (%s)\n", error_message(ret))); - goto out; - } + /* Try secrets.tdb first and fallback to the krb5.keytab if + necessary */ - if (lp_use_kerberos_keytab()) { - auth_ok = ads_keytab_verify_ticket(context, auth_context, ticket, &tkt, &keyblock, &ret); - } - if (!auth_ok) { - auth_ok = ads_secrets_verify_ticket(context, auth_context, host_princ, - ticket, &tkt, &keyblock, &ret); - } + auth_ok = ads_secrets_verify_ticket(context, auth_context, host_princ, + ticket, &tkt, &keyblock, &ret); - release_server_mutex(); - got_replay_mutex = False; + if (!auth_ok && lp_use_kerberos_keytab()) { + auth_ok = ads_keytab_verify_ticket(context, auth_context, + ticket, &tkt, &keyblock, &ret); + } + if ( use_replay_cache ) { + release_server_mutex(); + got_replay_mutex = False; #if 0 - /* Heimdal leaks here, if we fix the leak, MIT crashes */ - if (rcache) { - krb5_rc_close(context, rcache); - } + /* Heimdal leaks here, if we fix the leak, MIT crashes */ + if (rcache) { + krb5_rc_close(context, rcache); + } #endif + } if (!auth_ok) { DEBUG(3,("ads_verify_ticket: krb5_rd_req with auth failed (%s)\n", -- cgit From b4a39dc10e751fcb84d1f9709217eaf1b5da325a Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 13 Jun 2007 21:59:39 +0000 Subject: r23477: Build farm fix: Use int rather than MIT's krb5_int32 when setting context flags. (This used to be commit 903145e957cd05b219fdf7d5fc1e35430938a24e) --- source3/libads/kerberos_verify.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index ecd0f0869c..cfe9eeb7a2 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -325,7 +325,7 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, krb5_keyblock *keyblock = NULL; time_t authtime; krb5_error_code ret = 0; - krb5_int32 flags = 0; + int flags = 0; krb5_principal host_princ = NULL; krb5_const_principal client_principal = NULL; char *host_princ_s = NULL; -- cgit From 5a80fa5c0c461404f6f4dc3b4218d6f235796fff Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 16 Jun 2007 00:39:52 +0000 Subject: r23514: Remove unused function ads_get_dn_from_extended_dn(). Jeremy. (This used to be commit 03763bc5287fef5f100c911041668e23d4305f8d) --- source3/libads/ldap.c | 29 ----------------------------- 1 file changed, 29 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 5b87017d84..d60afcd0d5 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2768,35 +2768,6 @@ ADS_STATUS ads_upn_suffixes(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char ***suffix return status; } -/** - * pull a dn from an extended dn string - * @param mem_ctx TALLOC_CTX - * @param extended_dn string - * @param dn pointer to the dn - * @return boolean inidicating success - **/ -BOOL ads_get_dn_from_extended_dn(TALLOC_CTX *mem_ctx, - const char *extended_dn, - char **dn) -{ - char *p; - pstring tok; - - if (!extended_dn) { - return False; - } - - while (next_token(&extended_dn, tok, ";", sizeof(tok))) { - p = tok; - } - - if ((*dn = talloc_strdup(mem_ctx, p)) == NULL) { - return False; - } - - return True; -} - /** * pull a DOM_SID from an extended dn string * @param mem_ctx TALLOC_CTX -- cgit From 47bd42ab1c0c5de62e0692f152c01df80abecdeb Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 26 Jun 2007 09:15:37 +0000 Subject: r23607: Add legacy support for Services for Unix (SFU) 2.0. Guenther (This used to be commit 11b390309b9677805e5b68f3a1b780658ae85137) --- source3/libads/ldap_schema.c | 72 +++++++++++++++++++++++++++++++++----------- 1 file changed, 55 insertions(+), 17 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap_schema.c b/source3/libads/ldap_schema.c index 5d91d98549..a8b93cbdbc 100644 --- a/source3/libads/ldap_schema.c +++ b/source3/libads/ldap_schema.c @@ -205,13 +205,37 @@ ADS_STATUS ads_check_posix_schema_mapping(TALLOC_CTX *mem_ctx, ADS_ATTR_SFU_SHELL_OID, ADS_ATTR_SFU_GECOS_OID}; + const char *oids_sfu20[] = { ADS_ATTR_SFU20_UIDNUMBER_OID, + ADS_ATTR_SFU20_GIDNUMBER_OID, + ADS_ATTR_SFU20_HOMEDIR_OID, + ADS_ATTR_SFU20_SHELL_OID, + ADS_ATTR_SFU20_GECOS_OID}; + const char *oids_rfc2307[] = { ADS_ATTR_RFC2307_UIDNUMBER_OID, ADS_ATTR_RFC2307_GIDNUMBER_OID, ADS_ATTR_RFC2307_HOMEDIR_OID, ADS_ATTR_RFC2307_SHELL_OID, ADS_ATTR_RFC2307_GECOS_OID }; - DEBUG(10,("ads_check_posix_schema_mapping\n")); + DEBUG(10,("ads_check_posix_schema_mapping for schema mode: %d\n", map_type)); + + switch (map_type) { + + case WB_POSIX_MAP_TEMPLATE: + case WB_POSIX_MAP_UNIXINFO: + DEBUG(10,("ads_check_posix_schema_mapping: nothing to do\n")); + return ADS_ERROR(LDAP_SUCCESS); + + case WB_POSIX_MAP_SFU: + case WB_POSIX_MAP_SFU20: + case WB_POSIX_MAP_RFC2307: + break; + + default: + DEBUG(0,("ads_check_posix_schema_mapping: " + "unknown enum %d\n", map_type)); + return ADS_ERROR(LDAP_PARAM_ERROR); + } if ( (ctx = talloc_init("ads_check_posix_schema_mapping")) == NULL ) { return ADS_ERROR(LDAP_NO_MEMORY); @@ -228,14 +252,25 @@ ADS_STATUS ads_check_posix_schema_mapping(TALLOC_CTX *mem_ctx, goto done; } - if (map_type == WB_POSIX_MAP_SFU) { - status = ads_get_attrnames_by_oids(ads, ctx, schema_path, oids_sfu, - ARRAY_SIZE(oids_sfu), - &oids_out, &names_out, &num_names); - } else { - status = ads_get_attrnames_by_oids(ads, ctx, schema_path, oids_rfc2307, - ARRAY_SIZE(oids_rfc2307), - &oids_out, &names_out, &num_names); + switch (map_type) { + case WB_POSIX_MAP_SFU: + status = ads_get_attrnames_by_oids(ads, ctx, schema_path, oids_sfu, + ARRAY_SIZE(oids_sfu), + &oids_out, &names_out, &num_names); + break; + case WB_POSIX_MAP_SFU20: + status = ads_get_attrnames_by_oids(ads, ctx, schema_path, oids_sfu20, + ARRAY_SIZE(oids_sfu20), + &oids_out, &names_out, &num_names); + break; + case WB_POSIX_MAP_RFC2307: + status = ads_get_attrnames_by_oids(ads, ctx, schema_path, oids_rfc2307, + ARRAY_SIZE(oids_rfc2307), + &oids_out, &names_out, &num_names); + break; + default: + status = ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); + break; } if (!ADS_ERR_OK(status)) { @@ -249,31 +284,36 @@ ADS_STATUS ads_check_posix_schema_mapping(TALLOC_CTX *mem_ctx, DEBUGADD(10,("\tOID %s has name: %s\n", oids_out[i], names_out[i])); if (strequal(ADS_ATTR_RFC2307_UIDNUMBER_OID, oids_out[i]) || - strequal(ADS_ATTR_SFU_UIDNUMBER_OID, oids_out[i])) { + strequal(ADS_ATTR_SFU_UIDNUMBER_OID, oids_out[i]) || + strequal(ADS_ATTR_SFU20_UIDNUMBER_OID, oids_out[i])) { schema->posix_uidnumber_attr = talloc_strdup(schema, names_out[i]); continue; } if (strequal(ADS_ATTR_RFC2307_GIDNUMBER_OID, oids_out[i]) || - strequal(ADS_ATTR_SFU_GIDNUMBER_OID, oids_out[i])) { + strequal(ADS_ATTR_SFU_GIDNUMBER_OID, oids_out[i]) || + strequal(ADS_ATTR_SFU20_GIDNUMBER_OID, oids_out[i])) { schema->posix_gidnumber_attr = talloc_strdup(schema, names_out[i]); continue; } if (strequal(ADS_ATTR_RFC2307_HOMEDIR_OID, oids_out[i]) || - strequal(ADS_ATTR_SFU_HOMEDIR_OID, oids_out[i])) { + strequal(ADS_ATTR_SFU_HOMEDIR_OID, oids_out[i]) || + strequal(ADS_ATTR_SFU20_HOMEDIR_OID, oids_out[i])) { schema->posix_homedir_attr = talloc_strdup(schema, names_out[i]); continue; } if (strequal(ADS_ATTR_RFC2307_SHELL_OID, oids_out[i]) || - strequal(ADS_ATTR_SFU_SHELL_OID, oids_out[i])) { + strequal(ADS_ATTR_SFU_SHELL_OID, oids_out[i]) || + strequal(ADS_ATTR_SFU20_SHELL_OID, oids_out[i])) { schema->posix_shell_attr = talloc_strdup(schema, names_out[i]); continue; } if (strequal(ADS_ATTR_RFC2307_GECOS_OID, oids_out[i]) || - strequal(ADS_ATTR_SFU_GECOS_OID, oids_out[i])) { + strequal(ADS_ATTR_SFU_GECOS_OID, oids_out[i]) || + strequal(ADS_ATTR_SFU20_GECOS_OID, oids_out[i])) { schema->posix_gecos_attr = talloc_strdup(schema, names_out[i]); } } @@ -293,9 +333,7 @@ ADS_STATUS ads_check_posix_schema_mapping(TALLOC_CTX *mem_ctx, status = ADS_ERROR(LDAP_SUCCESS); done: - if (ctx) { - talloc_destroy(ctx); - } + TALLOC_FREE(ctx); return status; } -- cgit From df63172ad9b6460dc05bead8629b78b9a44f5b7c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 29 Jun 2007 08:56:35 +0000 Subject: r23646: Generalize our internal keytab handling to support a broader range of default keytabnames (like "ANY:FILE:/etc/krb5.keytab,krb4:/etc/srvtab"). This also fixes keytab support with Heimdal (which supports the WRFILE pragma as well now). Guenther (This used to be commit 7ca002f4cc9ec4139c0c48952ebf05f89b5795ef) --- source3/libads/kerberos_keytab.c | 187 +++++++++++++++++++++++++++++---------- 1 file changed, 140 insertions(+), 47 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c index d99e322b99..95a3a37712 100644 --- a/source3/libads/kerberos_keytab.c +++ b/source3/libads/kerberos_keytab.c @@ -5,7 +5,7 @@ Copyright (C) Remus Koos 2001 Copyright (C) Luke Howard 2003 Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003 - Copyright (C) Guenther Deschner 2003 + Copyright (C) Guenther Deschner 2003,2007 Copyright (C) Rakesh Patel 2004 Copyright (C) Dan Perry 2004 Copyright (C) Jeremy Allison 2004 @@ -35,6 +35,136 @@ #define MAX_KEYTAB_NAME_LEN 1100 #endif +/********************************************************************** + * Open a krb5 keytab with flags, handles readonly or readwrite access and + * allows to process non-default keytab names. + * @param context krb5_context + * @param keytab_name_req string + * @param write_access BOOL if writable keytab is required + * @param krb5_keytab pointer to krb5_keytab (close with krb5_kt_close()) + * @return krb5_error_code +**********************************************************************/ + + krb5_error_code smb_krb5_open_keytab(krb5_context context, + const char *keytab_name_req, + BOOL write_access, + krb5_keytab *keytab) +{ + krb5_error_code ret = 0; + TALLOC_CTX *mem_ctx; + char keytab_string[MAX_KEYTAB_NAME_LEN]; + BOOL found_valid_name = False; + const char *pragma = "FILE"; + const char *tmp = NULL; + + if (!write_access && !keytab_name_req) { + /* caller just wants to read the default keytab readonly, so be it */ + return krb5_kt_default(context, keytab); + } + + mem_ctx = talloc_init("smb_krb5_open_keytab"); + if (!mem_ctx) { + return ENOMEM; + } + +#ifdef HAVE_WRFILE_KEYTAB + if (write_access) { + pragma = "WRFILE"; + } +#endif + + if (keytab_name_req) { + + if (strlen(keytab_name_req) > MAX_KEYTAB_NAME_LEN) { + ret = KRB5_CONFIG_NOTENUFSPACE; + goto out; + } + + if ((strncmp(keytab_name_req, "WRFILE:/", 8) == 0) || + (strncmp(keytab_name_req, "FILE:/", 6) == 0)) { + tmp = keytab_name_req; + goto resolve; + } + + if (keytab_name_req[0] != '/') { + ret = KRB5_KT_BADNAME; + goto out; + } + + tmp = talloc_asprintf(mem_ctx, "%s:%s", pragma, keytab_name_req); + if (!tmp) { + ret = ENOMEM; + goto out; + } + + goto resolve; + } + + /* we need to handle more complex keytab_strings, like: + * "ANY:FILE:/etc/krb5.keytab,krb4:/etc/srvtab" */ + + ret = krb5_kt_default_name(context, &keytab_string[0], MAX_KEYTAB_NAME_LEN - 2); + if (ret) { + goto out; + } + + DEBUG(10,("smb_krb5_open_keytab: krb5_kt_default_name returned %s\n", keytab_string)); + + tmp = talloc_strdup(mem_ctx, keytab_string); + if (!tmp) { + ret = ENOMEM; + goto out; + } + + if (strncmp(tmp, "ANY:", 4) == 0) { + tmp += 4; + } + + memset(&keytab_string, '\0', sizeof(keytab_string)); + + while (next_token(&tmp, keytab_string, ",", sizeof(keytab_string))) { + + if (strncmp(keytab_string, "WRFILE:", 7) == 0) { + found_valid_name = True; + tmp = keytab_string; + tmp += 7; + } + + if (strncmp(keytab_string, "FILE:", 5) == 0) { + found_valid_name = True; + tmp = keytab_string; + tmp += 5; + } + + if (found_valid_name) { + + if (tmp[0] != '/') { + ret = KRB5_KT_BADNAME; + goto out; + } + + tmp = talloc_asprintf(mem_ctx, "%s:%s", pragma, tmp); + if (!tmp) { + ret = ENOMEM; + goto out; + } + break; + } + } + + if (!found_valid_name) { + ret = KRB5_KT_UNKNOWN_TYPE; + goto out; + } + + resolve: + DEBUG(10,("smb_krb5_open_keytab: resolving: %s\n", tmp)); + ret = krb5_kt_resolve(context, tmp, keytab); + + out: + TALLOC_FREE(mem_ctx); + return ret; +} /********************************************************************** **********************************************************************/ @@ -231,7 +361,6 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc) char *princ_s = NULL, *short_princ_s = NULL; char *password_s = NULL; char *my_fqdn; - char keytab_name[MAX_KEYTAB_NAME_LEN]; TALLOC_CTX *ctx = NULL; char *machine_name; @@ -245,22 +374,10 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc) DEBUG(1,("ads_keytab_add_entry: could not krb5_init_context: %s\n",error_message(ret))); return -1; } - -#ifdef HAVE_WRFILE_KEYTAB /* MIT */ - keytab_name[0] = 'W'; - keytab_name[1] = 'R'; - ret = krb5_kt_default_name(context, (char *) &keytab_name[2], MAX_KEYTAB_NAME_LEN - 4); -#else /* Heimdal */ - ret = krb5_kt_default_name(context, (char *) &keytab_name[0], MAX_KEYTAB_NAME_LEN - 2); -#endif - if (ret) { - DEBUG(1,("ads_keytab_add_entry: krb5_kt_default_name failed (%s)\n", error_message(ret))); - goto out; - } - DEBUG(2,("ads_keytab_add_entry: Using default system keytab: %s\n", (char *) &keytab_name)); - ret = krb5_kt_resolve(context, (char *) &keytab_name, &keytab); + + ret = smb_krb5_open_keytab(context, NULL, True, &keytab); if (ret) { - DEBUG(1,("ads_keytab_add_entry: krb5_kt_resolve failed (%s)\n", error_message(ret))); + DEBUG(1,("ads_keytab_add_entry: smb_krb5_open_keytab failed (%s)\n", error_message(ret))); goto out; } @@ -383,7 +500,6 @@ int ads_keytab_flush(ADS_STRUCT *ads) krb5_kt_cursor cursor; krb5_keytab_entry kt_entry; krb5_kvno kvno; - char keytab_name[MAX_KEYTAB_NAME_LEN]; ZERO_STRUCT(kt_entry); ZERO_STRUCT(cursor); @@ -394,21 +510,10 @@ int ads_keytab_flush(ADS_STRUCT *ads) DEBUG(1,("ads_keytab_flush: could not krb5_init_context: %s\n",error_message(ret))); return ret; } -#ifdef HAVE_WRFILE_KEYTAB - keytab_name[0] = 'W'; - keytab_name[1] = 'R'; - ret = krb5_kt_default_name(context, (char *) &keytab_name[2], MAX_KEYTAB_NAME_LEN - 4); -#else - ret = krb5_kt_default_name(context, (char *) &keytab_name[0], MAX_KEYTAB_NAME_LEN - 2); -#endif - if (ret) { - DEBUG(1,("ads_keytab_flush: krb5_kt_default failed (%s)\n", error_message(ret))); - goto out; - } - DEBUG(3,("ads_keytab_flush: Using default keytab: %s\n", (char *) &keytab_name)); - ret = krb5_kt_resolve(context, (char *) &keytab_name, &keytab); + + ret = smb_krb5_open_keytab(context, NULL, True, &keytab); if (ret) { - DEBUG(1,("ads_keytab_flush: krb5_kt_resolve failed (%s)\n", error_message(ret))); + DEBUG(1,("ads_keytab_flush: smb_krb5_open_keytab failed (%s)\n", error_message(ret))); goto out; } @@ -703,7 +808,6 @@ int ads_keytab_list(void) krb5_keytab keytab = NULL; krb5_kt_cursor cursor; krb5_keytab_entry kt_entry; - char keytab_name[MAX_KEYTAB_NAME_LEN]; ZERO_STRUCT(kt_entry); ZERO_STRUCT(cursor); @@ -714,21 +818,10 @@ int ads_keytab_list(void) DEBUG(1,("ads_keytab_list: could not krb5_init_context: %s\n",error_message(ret))); return ret; } -#if 0 /* HAVE_WRFILE_KEYTAB */ - keytab_name[0] = 'W'; - keytab_name[1] = 'R'; - ret = krb5_kt_default_name(context, (char *) &keytab_name[2], MAX_KEYTAB_NAME_LEN - 4); -#else - ret = krb5_kt_default_name(context, (char *) &keytab_name[0], MAX_KEYTAB_NAME_LEN - 2); -#endif - if (ret) { - DEBUG(1,("ads_keytab_list: krb5_kt_default failed (%s)\n", error_message(ret))); - goto out; - } - DEBUG(3,("ads_keytab_list: Using default keytab: %s\n", (char *) &keytab_name)); - ret = krb5_kt_resolve(context, (char *) &keytab_name, &keytab); + + ret = smb_krb5_open_keytab(context, NULL, False, &keytab); if (ret) { - DEBUG(1,("ads_keytab_list: krb5_kt_resolve failed (%s)\n", error_message(ret))); + DEBUG(1,("ads_keytab_list: smb_krb5_open_keytab failed (%s)\n", error_message(ret))); goto out; } -- cgit From 6fff735da0f9243761c410b39b876358a99fb9a8 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 29 Jun 2007 08:58:03 +0000 Subject: r23647: Use smb_krb5_open_keytab() in smbd as well. Guenther (This used to be commit d22c0d291e1b4a1412164d257310bbbb99de6500) --- source3/libads/kerberos_verify.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index cfe9eeb7a2..2eb5d66092 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -81,9 +81,9 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, ZERO_STRUCT(kt_entry); ZERO_STRUCT(kt_cursor); - ret = krb5_kt_default(context, &keytab); + ret = smb_krb5_open_keytab(context, NULL, False, &keytab); if (ret) { - DEBUG(1, ("ads_keytab_verify_ticket: krb5_kt_default failed (%s)\n", error_message(ret))); + DEBUG(1, ("ads_keytab_verify_ticket: smb_krb5_open_keytab failed (%s)\n", error_message(ret))); goto out; } -- cgit From a2618aa8d5a46305c02a083b880ce299681810c3 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 29 Jun 2007 09:01:29 +0000 Subject: r23648: Allow to list a custom krb5 keytab file with: net ads keytab list /path/to/krb5.keytab Guenther (This used to be commit a2befee3f240543ea02ea99cebad886b54ae64eb) --- source3/libads/kerberos_keytab.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c index 95a3a37712..a1038e1f2d 100644 --- a/source3/libads/kerberos_keytab.c +++ b/source3/libads/kerberos_keytab.c @@ -801,7 +801,7 @@ done: List system keytab. ***********************************************************************/ -int ads_keytab_list(void) +int ads_keytab_list(const char *keytab_name) { krb5_error_code ret = 0; krb5_context context = NULL; @@ -819,7 +819,7 @@ int ads_keytab_list(void) return ret; } - ret = smb_krb5_open_keytab(context, NULL, False, &keytab); + ret = smb_krb5_open_keytab(context, keytab_name, False, &keytab); if (ret) { DEBUG(1,("ads_keytab_list: smb_krb5_open_keytab failed (%s)\n", error_message(ret))); goto out; -- cgit From a24867293257585260deb0587e7e1b710654843a Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 29 Jun 2007 09:42:14 +0000 Subject: r23649: Fix the build (by moving smb_krb5_open_keytab() to clikrb5.c). Guenther (This used to be commit 19020d19dca7f34be92c8c2ec49ae7dbde60f8c1) --- source3/libads/kerberos_keytab.c | 138 +-------------------------------------- 1 file changed, 1 insertion(+), 137 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c index a1038e1f2d..d86b902ad5 100644 --- a/source3/libads/kerberos_keytab.c +++ b/source3/libads/kerberos_keytab.c @@ -5,7 +5,7 @@ Copyright (C) Remus Koos 2001 Copyright (C) Luke Howard 2003 Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003 - Copyright (C) Guenther Deschner 2003,2007 + Copyright (C) Guenther Deschner 2003 Copyright (C) Rakesh Patel 2004 Copyright (C) Dan Perry 2004 Copyright (C) Jeremy Allison 2004 @@ -30,142 +30,6 @@ #ifdef HAVE_KRB5 -/* This MAX_NAME_LEN is a constant defined in krb5.h */ -#ifndef MAX_KEYTAB_NAME_LEN -#define MAX_KEYTAB_NAME_LEN 1100 -#endif - -/********************************************************************** - * Open a krb5 keytab with flags, handles readonly or readwrite access and - * allows to process non-default keytab names. - * @param context krb5_context - * @param keytab_name_req string - * @param write_access BOOL if writable keytab is required - * @param krb5_keytab pointer to krb5_keytab (close with krb5_kt_close()) - * @return krb5_error_code -**********************************************************************/ - - krb5_error_code smb_krb5_open_keytab(krb5_context context, - const char *keytab_name_req, - BOOL write_access, - krb5_keytab *keytab) -{ - krb5_error_code ret = 0; - TALLOC_CTX *mem_ctx; - char keytab_string[MAX_KEYTAB_NAME_LEN]; - BOOL found_valid_name = False; - const char *pragma = "FILE"; - const char *tmp = NULL; - - if (!write_access && !keytab_name_req) { - /* caller just wants to read the default keytab readonly, so be it */ - return krb5_kt_default(context, keytab); - } - - mem_ctx = talloc_init("smb_krb5_open_keytab"); - if (!mem_ctx) { - return ENOMEM; - } - -#ifdef HAVE_WRFILE_KEYTAB - if (write_access) { - pragma = "WRFILE"; - } -#endif - - if (keytab_name_req) { - - if (strlen(keytab_name_req) > MAX_KEYTAB_NAME_LEN) { - ret = KRB5_CONFIG_NOTENUFSPACE; - goto out; - } - - if ((strncmp(keytab_name_req, "WRFILE:/", 8) == 0) || - (strncmp(keytab_name_req, "FILE:/", 6) == 0)) { - tmp = keytab_name_req; - goto resolve; - } - - if (keytab_name_req[0] != '/') { - ret = KRB5_KT_BADNAME; - goto out; - } - - tmp = talloc_asprintf(mem_ctx, "%s:%s", pragma, keytab_name_req); - if (!tmp) { - ret = ENOMEM; - goto out; - } - - goto resolve; - } - - /* we need to handle more complex keytab_strings, like: - * "ANY:FILE:/etc/krb5.keytab,krb4:/etc/srvtab" */ - - ret = krb5_kt_default_name(context, &keytab_string[0], MAX_KEYTAB_NAME_LEN - 2); - if (ret) { - goto out; - } - - DEBUG(10,("smb_krb5_open_keytab: krb5_kt_default_name returned %s\n", keytab_string)); - - tmp = talloc_strdup(mem_ctx, keytab_string); - if (!tmp) { - ret = ENOMEM; - goto out; - } - - if (strncmp(tmp, "ANY:", 4) == 0) { - tmp += 4; - } - - memset(&keytab_string, '\0', sizeof(keytab_string)); - - while (next_token(&tmp, keytab_string, ",", sizeof(keytab_string))) { - - if (strncmp(keytab_string, "WRFILE:", 7) == 0) { - found_valid_name = True; - tmp = keytab_string; - tmp += 7; - } - - if (strncmp(keytab_string, "FILE:", 5) == 0) { - found_valid_name = True; - tmp = keytab_string; - tmp += 5; - } - - if (found_valid_name) { - - if (tmp[0] != '/') { - ret = KRB5_KT_BADNAME; - goto out; - } - - tmp = talloc_asprintf(mem_ctx, "%s:%s", pragma, tmp); - if (!tmp) { - ret = ENOMEM; - goto out; - } - break; - } - } - - if (!found_valid_name) { - ret = KRB5_KT_UNKNOWN_TYPE; - goto out; - } - - resolve: - DEBUG(10,("smb_krb5_open_keytab: resolving: %s\n", tmp)); - ret = krb5_kt_resolve(context, tmp, keytab); - - out: - TALLOC_FREE(mem_ctx); - return ret; -} - /********************************************************************** **********************************************************************/ -- cgit From 3b1956f9d2ad36dfc8c10a4ce22ee05a138bd2f9 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 29 Jun 2007 09:54:39 +0000 Subject: r23650: Fix remaining callers of krb5_kt_default(). Guenther (This used to be commit b9d7a2962a472afb0c6b8e3ac5c2c819d4af2b39) --- source3/libads/kerberos_keytab.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c index d86b902ad5..7847b689c2 100644 --- a/source3/libads/kerberos_keytab.c +++ b/source3/libads/kerberos_keytab.c @@ -546,10 +546,11 @@ int ads_keytab_create_default(ADS_STRUCT *ads) DEBUG(1,("ads_keytab_create_default: could not krb5_init_context: %s\n",error_message(ret))); return ret; } - ret = krb5_kt_default(context, &keytab); + + ret = smb_krb5_open_keytab(context, NULL, True, &keytab); if (ret) { - DEBUG(1,("ads_keytab_create_default: krb5_kt_default failed (%s)\n",error_message(ret))); - goto done; + DEBUG(1,("ads_keytab_create_default: smb_krb5_open_keytab failed (%s)\n", error_message(ret))); + goto out; } ret = krb5_kt_start_seq_get(context, keytab, &cursor); -- cgit From 110e420196bcaf87d8d434b3680100d9b265a879 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 29 Jun 2007 09:58:11 +0000 Subject: r23651: Always, always, always compile before commit... Guenther (This used to be commit accb40446ad3f872c5167fc2306d892553293b7b) --- source3/libads/kerberos_keytab.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c index 7847b689c2..46d00ba8c4 100644 --- a/source3/libads/kerberos_keytab.c +++ b/source3/libads/kerberos_keytab.c @@ -550,7 +550,7 @@ int ads_keytab_create_default(ADS_STRUCT *ads) ret = smb_krb5_open_keytab(context, NULL, True, &keytab); if (ret) { DEBUG(1,("ads_keytab_create_default: smb_krb5_open_keytab failed (%s)\n", error_message(ret))); - goto out; + goto done; } ret = krb5_kt_start_seq_get(context, keytab, &cursor); -- cgit From 8ead92f06d11ae1cbedf2b700bdbf96da5602a1d Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 29 Jun 2007 11:54:29 +0000 Subject: r23654: Remove misleading inline comment. Guenther (This used to be commit a3441c22b342e2802bd9766b7046073db3895a29) --- source3/libads/dns.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/dns.c b/source3/libads/dns.c index e0e696c99c..c0d8d61e36 100644 --- a/source3/libads/dns.c +++ b/source3/libads/dns.c @@ -637,8 +637,6 @@ static char *sitename_key(const char *realm) /**************************************************************************** Store the AD client sitename. We store indefinately as every new CLDAP query will re-write this. - If the sitename is "Default-First-Site-Name" we don't store it - as this isn't a valid DNS name. ****************************************************************************/ BOOL sitename_store(const char *realm, const char *sitename) @@ -652,7 +650,7 @@ BOOL sitename_store(const char *realm, const char *sitename) } if (!realm || (strlen(realm) == 0)) { - DEBUG(0,("no realm\n")); + DEBUG(0,("sitename_store: no realm\n")); return False; } @@ -723,7 +721,7 @@ BOOL stored_sitename_changed(const char *realm, const char *sitename) char *new_sitename; if (!realm || (strlen(realm) == 0)) { - DEBUG(0,("no realm\n")); + DEBUG(0,("stored_sitename_changed: no realm\n")); return False; } -- cgit From 221d06d6f3e9789bf3efc6fa52dd94e68b1804cf Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 9 Jul 2007 16:03:00 +0000 Subject: r23772: Add ads_find_samaccount() helper function. Guenther (This used to be commit 6fafa64bea4ce6a7a5917fa02ed9c564a7c93ffb) --- source3/libads/ldap.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index d60afcd0d5..6f0ca3452c 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -3272,4 +3272,64 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) return ADS_ERROR_LDAP(LDAP_SUCCESS); } +ADS_STATUS ads_find_samaccount(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + const char *samaccountname, + uint32 *uac_ret, + const char **dn_ret) +{ + ADS_STATUS status; + const char *attrs[] = { "userAccountControl", NULL }; + const char *filter; + LDAPMessage *res = NULL; + char *dn = NULL; + uint32 uac = 0; + + filter = talloc_asprintf(mem_ctx, "(&(objectclass=user)(sAMAccountName=%s))", + samaccountname); + if (filter == NULL) { + goto out; + } + + status = ads_do_search_all(ads, ads->config.bind_path, + LDAP_SCOPE_SUBTREE, + filter, attrs, &res); + + if (!ADS_ERR_OK(status)) { + goto out; + } + + if (ads_count_replies(ads, res) != 1) { + printf("no result\n"); + goto out; + } + + dn = ads_get_dn(ads, res); + if (dn == NULL) { + status = ADS_ERROR(LDAP_NO_MEMORY); + goto out; + } + + if (!ads_pull_uint32(ads, res, "userAccountControl", &uac)) { + status = ADS_ERROR(LDAP_NO_SUCH_ATTRIBUTE); + goto out; + } + + if (uac_ret) { + *uac_ret = uac; + } + + if (dn_ret) { + *dn_ret = talloc_strdup(mem_ctx, dn); + if (!*dn_ret) { + status = ADS_ERROR(LDAP_NO_MEMORY); + goto out; + } + } + out: + ads_memfree(ads, dn); + ads_msgfree(ads, res); + + return status; +} #endif -- cgit From d824b98f80ba186030cbb70b3a1e5daf80469ecd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 9 Jul 2007 19:25:36 +0000 Subject: r23779: Change from v2 or later to v3 or later. Jeremy. (This used to be commit 407e6e695b8366369b7c76af1ff76869b45347b3) --- source3/libads/ads_status.c | 2 +- source3/libads/ads_struct.c | 2 +- source3/libads/ads_utils.c | 2 +- source3/libads/authdata.c | 2 +- source3/libads/cldap.c | 2 +- source3/libads/disp_sec.c | 2 +- source3/libads/dns.c | 2 +- source3/libads/kerberos.c | 2 +- source3/libads/kerberos_keytab.c | 2 +- source3/libads/kerberos_verify.c | 2 +- source3/libads/krb5_errs.c | 2 +- source3/libads/krb5_setpw.c | 2 +- source3/libads/ldap.c | 2 +- source3/libads/ldap_printer.c | 2 +- source3/libads/ldap_schema.c | 2 +- source3/libads/ldap_user.c | 2 +- source3/libads/ldap_utils.c | 2 +- source3/libads/sasl.c | 2 +- source3/libads/smb_krb5_locator.c | 2 +- source3/libads/util.c | 2 +- 20 files changed, 20 insertions(+), 20 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_status.c b/source3/libads/ads_status.c index 48c03a6a14..b9b131d546 100644 --- a/source3/libads/ads_status.c +++ b/source3/libads/ads_status.c @@ -8,7 +8,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index 05f066c9fa..9347777eab 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -6,7 +6,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libads/ads_utils.c b/source3/libads/ads_utils.c index 5b450e02dd..d451b0aebc 100644 --- a/source3/libads/ads_utils.c +++ b/source3/libads/ads_utils.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c index 9dfb9cba09..86e3e9edcf 100644 --- a/source3/libads/authdata.c +++ b/source3/libads/authdata.c @@ -10,7 +10,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libads/cldap.c b/source3/libads/cldap.c index 227bbc2a0a..041a92d5c9 100644 --- a/source3/libads/cldap.c +++ b/source3/libads/cldap.c @@ -6,7 +6,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libads/disp_sec.c b/source3/libads/disp_sec.c index 1e62eb8551..6f3f2cd015 100644 --- a/source3/libads/disp_sec.c +++ b/source3/libads/disp_sec.c @@ -5,7 +5,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libads/dns.c b/source3/libads/dns.c index c0d8d61e36..d2f2c12522 100644 --- a/source3/libads/dns.c +++ b/source3/libads/dns.c @@ -5,7 +5,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 841674bea5..ac49408a0a 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -9,7 +9,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c index 46d00ba8c4..ba07019fea 100644 --- a/source3/libads/kerberos_keytab.c +++ b/source3/libads/kerberos_keytab.c @@ -13,7 +13,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 2eb5d66092..12e8ee9955 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -11,7 +11,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libads/krb5_errs.c b/source3/libads/krb5_errs.c index 8216fefb64..0cc51830a7 100644 --- a/source3/libads/krb5_errs.c +++ b/source3/libads/krb5_errs.c @@ -5,7 +5,7 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 4aab09c9f4..735cafa524 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -6,7 +6,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 6f0ca3452c..a9e946e952 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -9,7 +9,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index f5168b05af..cf6e1e08b0 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -5,7 +5,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libads/ldap_schema.c b/source3/libads/ldap_schema.c index a8b93cbdbc..0f0b20c1bf 100644 --- a/source3/libads/ldap_schema.c +++ b/source3/libads/ldap_schema.c @@ -6,7 +6,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libads/ldap_user.c b/source3/libads/ldap_user.c index afbbc0b421..d3a9803cb8 100644 --- a/source3/libads/ldap_user.c +++ b/source3/libads/ldap_user.c @@ -5,7 +5,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libads/ldap_utils.c b/source3/libads/ldap_utils.c index 6417e92e92..30b1a26bca 100644 --- a/source3/libads/ldap_utils.c +++ b/source3/libads/ldap_utils.c @@ -8,7 +8,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index f1f0861535..3be7ee67b6 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -5,7 +5,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libads/smb_krb5_locator.c b/source3/libads/smb_krb5_locator.c index be14a12697..803aecf9a3 100644 --- a/source3/libads/smb_krb5_locator.c +++ b/source3/libads/smb_krb5_locator.c @@ -5,7 +5,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libads/util.c b/source3/libads/util.c index eb6dccb3af..5f0a33d90f 100644 --- a/source3/libads/util.c +++ b/source3/libads/util.c @@ -5,7 +5,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, -- cgit From 5e54558c6dea67b56bbfaba5698f3a434d3dffb6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 00:52:41 +0000 Subject: r23784: use the GPLv3 boilerplate as recommended by the FSF and the license text (This used to be commit b0132e94fc5fef936aa766fb99a306b3628e9f07) --- source3/libads/ads_status.c | 3 +-- source3/libads/ads_struct.c | 3 +-- source3/libads/ads_utils.c | 3 +-- source3/libads/authdata.c | 3 +-- source3/libads/cldap.c | 3 +-- source3/libads/disp_sec.c | 3 +-- source3/libads/dns.c | 3 +-- source3/libads/kerberos.c | 3 +-- source3/libads/kerberos_keytab.c | 3 +-- source3/libads/kerberos_verify.c | 3 +-- source3/libads/krb5_setpw.c | 3 +-- source3/libads/ldap.c | 3 +-- source3/libads/ldap_printer.c | 3 +-- source3/libads/ldap_schema.c | 3 +-- source3/libads/ldap_user.c | 3 +-- source3/libads/ldap_utils.c | 3 +-- source3/libads/sasl.c | 3 +-- source3/libads/smb_krb5_locator.c | 3 +-- source3/libads/util.c | 3 +-- 19 files changed, 19 insertions(+), 38 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_status.c b/source3/libads/ads_status.c index b9b131d546..742304b6fc 100644 --- a/source3/libads/ads_status.c +++ b/source3/libads/ads_status.c @@ -17,8 +17,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index 9347777eab..b01e0879ef 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -15,8 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libads/ads_utils.c b/source3/libads/ads_utils.c index d451b0aebc..68efd69db9 100644 --- a/source3/libads/ads_utils.c +++ b/source3/libads/ads_utils.c @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c index 86e3e9edcf..d61ffc2397 100644 --- a/source3/libads/authdata.c +++ b/source3/libads/authdata.c @@ -19,8 +19,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libads/cldap.c b/source3/libads/cldap.c index 041a92d5c9..de0e2e71e4 100644 --- a/source3/libads/cldap.c +++ b/source3/libads/cldap.c @@ -15,8 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libads/disp_sec.c b/source3/libads/disp_sec.c index 6f3f2cd015..60749dbb21 100644 --- a/source3/libads/disp_sec.c +++ b/source3/libads/disp_sec.c @@ -14,8 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libads/dns.c b/source3/libads/dns.c index d2f2c12522..96cd54af06 100644 --- a/source3/libads/dns.c +++ b/source3/libads/dns.c @@ -14,8 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index ac49408a0a..2cf0577687 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -18,8 +18,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c index ba07019fea..342e79ddd8 100644 --- a/source3/libads/kerberos_keytab.c +++ b/source3/libads/kerberos_keytab.c @@ -22,8 +22,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 12e8ee9955..378258ee08 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -20,8 +20,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 735cafa524..24220685f3 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -15,8 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index a9e946e952..dd2bf0e344 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -18,8 +18,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index cf6e1e08b0..cfddd4cc8a 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -14,8 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libads/ldap_schema.c b/source3/libads/ldap_schema.c index 0f0b20c1bf..f71f53adb6 100644 --- a/source3/libads/ldap_schema.c +++ b/source3/libads/ldap_schema.c @@ -15,8 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libads/ldap_user.c b/source3/libads/ldap_user.c index d3a9803cb8..bef2c91292 100644 --- a/source3/libads/ldap_user.c +++ b/source3/libads/ldap_user.c @@ -14,8 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libads/ldap_utils.c b/source3/libads/ldap_utils.c index 30b1a26bca..3ad08085bb 100644 --- a/source3/libads/ldap_utils.c +++ b/source3/libads/ldap_utils.c @@ -17,8 +17,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 3be7ee67b6..9536ba31be 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -14,8 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libads/smb_krb5_locator.c b/source3/libads/smb_krb5_locator.c index 803aecf9a3..b5a6ffd453 100644 --- a/source3/libads/smb_krb5_locator.c +++ b/source3/libads/smb_krb5_locator.c @@ -14,8 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libads/util.c b/source3/libads/util.c index 5f0a33d90f..2fb9fa81b4 100644 --- a/source3/libads/util.c +++ b/source3/libads/util.c @@ -14,8 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" -- cgit From 153cfb9c83534b09f15cc16205d7adb19b394928 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 05:23:25 +0000 Subject: r23801: The FSF has moved around a lot. This fixes their Mass Ave address. (This used to be commit 87c91e4362c51819032bfbebbb273c52e203b227) --- source3/libads/krb5_errs.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/krb5_errs.c b/source3/libads/krb5_errs.c index 0cc51830a7..53023cc75a 100644 --- a/source3/libads/krb5_errs.c +++ b/source3/libads/krb5_errs.c @@ -14,8 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * along with this program; if not, see . */ #include "includes.h" -- cgit From 6d0141c17e996cf1c0fb4aa69ab7a1c506657e0d Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 10 Jul 2007 21:04:57 +0000 Subject: r23820: Display security_ace_object in LDAP security descriptors for debugging. Guenther (This used to be commit 3925e85812b2aded356866925382b1beb718cd44) --- source3/libads/disp_sec.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/disp_sec.c b/source3/libads/disp_sec.c index 60749dbb21..1f5eb4166a 100644 --- a/source3/libads/disp_sec.c +++ b/source3/libads/disp_sec.c @@ -82,6 +82,20 @@ static void ads_disp_perms(uint32 type) puts(""); } +static void ads_disp_sec_ace_object(struct security_ace_object *object) +{ + if (object->flags & SEC_ACE_OBJECT_PRESENT) { + printf("Object type: SEC_ACE_OBJECT_PRESENT\n"); + printf("Object GUID: %s\n", smb_uuid_string_static( + object->type.type)); + } + if (object->flags & SEC_ACE_OBJECT_INHERITED_PRESENT) { + printf("Object type: SEC_ACE_OBJECT_INHERITED_PRESENT\n"); + printf("Object GUID: %s\n", smb_uuid_string_static( + object->inherited_type.inherited_type)); + } +} + /* display ACE */ static void ads_disp_ace(SEC_ACE *sec_ace) { @@ -119,6 +133,10 @@ static void ads_disp_ace(SEC_ACE *sec_ace) printf("access SID: %s\naccess type: %s\n", sid_string_static(&sec_ace->trustee), access_type); + if (sec_ace_object(sec_ace->type)) { + ads_disp_sec_ace_object(&sec_ace->object.object); + } + ads_disp_perms(sec_ace->access_mask); } -- cgit From 1c957f9559880712acd335c9df11191df0386df0 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 11 Jul 2007 09:39:08 +0000 Subject: r23826: Fix gpo security filtering by matching the security descriptor ace's for the extended apply group policy right. Guenther (This used to be commit d832014a6fef657f484412372b5d09047552b183) --- source3/libads/disp_sec.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/disp_sec.c b/source3/libads/disp_sec.c index 1f5eb4166a..516f204ed6 100644 --- a/source3/libads/disp_sec.c +++ b/source3/libads/disp_sec.c @@ -46,8 +46,6 @@ static struct perm_mask_str { {SEC_RIGHTS_CHANGE_PASSWD, "[Change Password]"}, {SEC_RIGHTS_RESET_PASSWD, "[Reset Password]"}, - {SEC_RIGHTS_APPLY_GROUP_POLICY, "[Apply Group Policy]"}, - {0, 0} }; -- cgit From e7705f9eb920715b95a331e2f3c1f1c60258ac18 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 11 Jul 2007 10:26:02 +0000 Subject: r23829: Add ads_get_attrname_by_guid(). Guenther (This used to be commit a84fd8300661fd895ed7a8a104b743628718dfc8) --- source3/libads/ldap_schema.c | 53 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap_schema.c b/source3/libads/ldap_schema.c index f71f53adb6..2672d88306 100644 --- a/source3/libads/ldap_schema.c +++ b/source3/libads/ldap_schema.c @@ -1,7 +1,7 @@ /* Unix SMB/CIFS implementation. ads (active directory) utility library - Copyright (C) Guenther Deschner 2005-2006 + Copyright (C) Guenther Deschner 2005-2007 Copyright (C) Gerald (Jerry) Carter 2006 This program is free software; you can redistribute it and/or modify @@ -106,6 +106,56 @@ out: return status; } +const char *ads_get_attrname_by_guid(ADS_STRUCT *ads, + const char *schema_path, + TALLOC_CTX *mem_ctx, + const char *schema_guid) +{ + ADS_STATUS rc; + LDAPMessage *res = NULL; + char *expr = NULL; + const char *attrs[] = { "lDAPDisplayName", NULL }; + const char *result = NULL; + struct GUID guid; + char *guid_bin = NULL; + + if (!ads || !mem_ctx || !schema_guid) { + goto done; + } + + if (!NT_STATUS_IS_OK(GUID_from_string(schema_guid, &guid))) { + goto done; + } + + guid_bin = guid_binstring(&guid); + if (!guid_bin) { + goto done; + } + + expr = talloc_asprintf(mem_ctx, "(schemaIDGUID=%s)", guid_bin); + if (!expr) { + goto done; + } + + rc = ads_do_search_retry(ads, schema_path, LDAP_SCOPE_SUBTREE, + expr, attrs, &res); + if (!ADS_ERR_OK(rc)) { + goto done; + } + + if (ads_count_replies(ads, res) != 1) { + goto done; + } + + result = ads_pull_string(ads, mem_ctx, res, "lDAPDisplayName"); + + done: + SAFE_FREE(guid_bin); + ads_msgfree(ads, res); + return result; + +} + const char *ads_get_attrname_by_oid(ADS_STRUCT *ads, const char *schema_path, TALLOC_CTX *mem_ctx, const char * OID) { ADS_STATUS rc; @@ -147,7 +197,6 @@ failed: ads_msgfree(ads, res); return NULL; } - /********************************************************************* *********************************************************************/ -- cgit From c8e23e4091a85063929aa7d807b0c1b7d7b98d91 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 11 Jul 2007 13:17:42 +0000 Subject: r23833: Document ads_find_samaccount(). Guenther (This used to be commit 3effd1c3461301f9ccf7c55386810c36f4ee3ccc) --- source3/libads/ldap.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index dd2bf0e344..40bba683a4 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -3271,6 +3271,15 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) return ADS_ERROR_LDAP(LDAP_SUCCESS); } +/** + * Find a sAMAccoutName in LDAP + * @param ads connection to ads server + * @param mem_ctx TALLOC_CTX for allocating sid array + * @param samaccountname to search + * @param uac_ret uint32 pointer userAccountControl attribute value + * @param dn_ret pointer to dn + * @return status of token query + **/ ADS_STATUS ads_find_samaccount(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char *samaccountname, -- cgit From c252b04abf31c2cade71a83e8e6c650d7c41f80b Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 11 Jul 2007 13:21:32 +0000 Subject: r23834: Allow to pass an ADS_STRUCT pointer down to the dump function callback in libads. Guenther (This used to be commit 311bbbafa6d860b7b632beac6d9249b0a2fafb86) --- source3/libads/ldap.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 40bba683a4..08ef13d039 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -839,7 +839,7 @@ static ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, **/ ADS_STATUS ads_do_search_all_fn(ADS_STRUCT *ads, const char *bind_path, int scope, const char *expr, const char **attrs, - BOOL(*fn)(char *, void **, void *), + BOOL(*fn)(ADS_STRUCT *, char *, void **, void *), void *data_area) { struct berval *cookie = NULL; @@ -1777,7 +1777,7 @@ done: /* dump a binary result from ldap */ -static void dump_binary(const char *field, struct berval **values) +static void dump_binary(ADS_STRUCT *ads, const char *field, struct berval **values) { int i, j; for (i=0; values[i]; i++) { @@ -1789,7 +1789,7 @@ static void dump_binary(const char *field, struct berval **values) } } -static void dump_guid(const char *field, struct berval **values) +static void dump_guid(ADS_STRUCT *ads, const char *field, struct berval **values) { int i; UUID_FLAT guid; @@ -1803,7 +1803,7 @@ static void dump_guid(const char *field, struct berval **values) /* dump a sid result from ldap */ -static void dump_sid(const char *field, struct berval **values) +static void dump_sid(ADS_STRUCT *ads, const char *field, struct berval **values) { int i; for (i=0; values[i]; i++) { @@ -1816,7 +1816,7 @@ static void dump_sid(const char *field, struct berval **values) /* dump ntSecurityDescriptor */ -static void dump_sd(const char *filed, struct berval **values) +static void dump_sd(ADS_STRUCT *ads, const char *filed, struct berval **values) { prs_struct ps; @@ -1859,12 +1859,12 @@ static void dump_string(const char *field, char **values) used for debugging */ -static BOOL ads_dump_field(char *field, void **values, void *data_area) +static BOOL ads_dump_field(ADS_STRUCT *ads, char *field, void **values, void *data_area) { const struct { const char *name; BOOL string; - void (*handler)(const char *, struct berval **); + void (*handler)(ADS_STRUCT *, const char *, struct berval **); } handlers[] = { {"objectGUID", False, dump_guid}, {"netbootGUID", False, dump_guid}, @@ -1888,7 +1888,7 @@ static BOOL ads_dump_field(char *field, void **values, void *data_area) if (StrCaseCmp(handlers[i].name, field) == 0) { if (!values) /* first time, indicate string or not */ return handlers[i].string; - handlers[i].handler(field, (struct berval **) values); + handlers[i].handler(ads, field, (struct berval **) values); break; } } @@ -1924,7 +1924,7 @@ static BOOL ads_dump_field(char *field, void **values, void *data_area) * @param data_area user-defined area to pass to function **/ void ads_process_results(ADS_STRUCT *ads, LDAPMessage *res, - BOOL(*fn)(char *, void **, void *), + BOOL(*fn)(ADS_STRUCT *, char *, void **, void *), void *data_area) { LDAPMessage *msg; @@ -1949,19 +1949,19 @@ static BOOL ads_dump_field(char *field, void **values, void *data_area) BOOL string; pull_utf8_talloc(ctx, &field, utf8_field); - string = fn(field, NULL, data_area); + string = fn(ads, field, NULL, data_area); if (string) { utf8_vals = ldap_get_values(ads->ld, (LDAPMessage *)msg, field); str_vals = ads_pull_strvals(ctx, (const char **) utf8_vals); - fn(field, (void **) str_vals, data_area); + fn(ads, field, (void **) str_vals, data_area); ldap_value_free(utf8_vals); } else { ber_vals = ldap_get_values_len(ads->ld, (LDAPMessage *)msg, field); - fn(field, (void **) ber_vals, data_area); + fn(ads, field, (void **) ber_vals, data_area); ldap_value_free_len(ber_vals); } @@ -1969,7 +1969,7 @@ static BOOL ads_dump_field(char *field, void **values, void *data_area) } ber_free(b, 0); talloc_free_children(ctx); - fn(NULL, NULL, data_area); /* completed an entry */ + fn(ads, NULL, NULL, data_area); /* completed an entry */ } talloc_destroy(ctx); -- cgit From fd8dc4b5610c840830a9498b16b69f56e6b73c31 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 11 Jul 2007 13:23:56 +0000 Subject: r23835: Pass down a struct GUID to ads_get_attrname_by_guid() directly. Guenther (This used to be commit a4d5206d0bcbee713790834f119b182e0b419e8c) --- source3/libads/ldap_schema.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap_schema.c b/source3/libads/ldap_schema.c index 2672d88306..1cdd51faca 100644 --- a/source3/libads/ldap_schema.c +++ b/source3/libads/ldap_schema.c @@ -109,25 +109,20 @@ out: const char *ads_get_attrname_by_guid(ADS_STRUCT *ads, const char *schema_path, TALLOC_CTX *mem_ctx, - const char *schema_guid) + const struct GUID *schema_guid) { ADS_STATUS rc; LDAPMessage *res = NULL; char *expr = NULL; const char *attrs[] = { "lDAPDisplayName", NULL }; const char *result = NULL; - struct GUID guid; char *guid_bin = NULL; if (!ads || !mem_ctx || !schema_guid) { goto done; } - if (!NT_STATUS_IS_OK(GUID_from_string(schema_guid, &guid))) { - goto done; - } - - guid_bin = guid_binstring(&guid); + guid_bin = guid_binstring(schema_guid); if (!guid_bin) { goto done; } -- cgit From f05dcab9bf3e929f796746420b784525fdf6113e Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 11 Jul 2007 13:26:04 +0000 Subject: r23836: Add ads_config_path() and ads_get_extended_right_name_by_guid(). Guenther (This used to be commit 4d62f1191b52569fcdbe674773b07a44aa469520) --- source3/libads/ldap.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 08ef13d039..a1d1a2d649 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -3340,4 +3340,97 @@ ADS_STATUS ads_find_samaccount(ADS_STRUCT *ads, return status; } + +/** + * find our configuration path + * @param ads connection to ads server + * @param mem_ctx Pointer to talloc context + * @param config_path Pointer to the config path + * @return status of search + **/ +ADS_STATUS ads_config_path(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + char **config_path) +{ + ADS_STATUS status; + LDAPMessage *res = NULL; + const char *config_context = NULL; + const char *attrs[] = { "configurationNamingContext", NULL }; + + status = ads_do_search(ads, "", LDAP_SCOPE_BASE, + "(objectclass=*)", attrs, &res); + if (!ADS_ERR_OK(status)) { + return status; + } + + config_context = ads_pull_string(ads, mem_ctx, res, + "configurationNamingContext"); + ads_msgfree(ads, res); + if (!config_context) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + + if (config_path) { + *config_path = talloc_strdup(mem_ctx, config_context); + if (!*config_path) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + } + + return ADS_ERROR(LDAP_SUCCESS); +} + +/** + * find the displayName of an extended right + * @param ads connection to ads server + * @param config_path The config path + * @param mem_ctx Pointer to talloc context + * @param GUID struct of the rightsGUID + * @return status of search + **/ +const char *ads_get_extended_right_name_by_guid(ADS_STRUCT *ads, + const char *config_path, + TALLOC_CTX *mem_ctx, + const struct GUID *rights_guid) +{ + ADS_STATUS rc; + LDAPMessage *res = NULL; + char *expr = NULL; + const char *attrs[] = { "displayName", NULL }; + const char *result = NULL; + const char *path; + + if (!ads || !mem_ctx || !rights_guid) { + goto done; + } + + expr = talloc_asprintf(mem_ctx, "(rightsGuid=%s)", + smb_uuid_string_static(*rights_guid)); + if (!expr) { + goto done; + } + + path = talloc_asprintf(mem_ctx, "cn=Extended-Rights,%s", config_path); + if (!path) { + goto done; + } + + rc = ads_do_search_retry(ads, path, LDAP_SCOPE_SUBTREE, + expr, attrs, &res); + if (!ADS_ERR_OK(rc)) { + goto done; + } + + if (ads_count_replies(ads, res) != 1) { + goto done; + } + + result = ads_pull_string(ads, mem_ctx, res, "displayName"); + + done: + ads_msgfree(ads, res); + return result; + +} + #endif -- cgit From 9d6f8ed5e7ece2a6bf7a9f51c7dc183932539ff5 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 11 Jul 2007 13:30:38 +0000 Subject: r23837: Pass ADS_STRUCT and TALLOC_CTX down to ads_disp_sd. Guenther (This used to be commit ad0a6d5703c35d48ab5bbfa8d6506d42e0cfb61d) --- source3/libads/disp_sec.c | 12 ++++++------ source3/libads/ldap.c | 4 +++- 2 files changed, 9 insertions(+), 7 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/disp_sec.c b/source3/libads/disp_sec.c index 516f204ed6..9ea332858f 100644 --- a/source3/libads/disp_sec.c +++ b/source3/libads/disp_sec.c @@ -80,7 +80,7 @@ static void ads_disp_perms(uint32 type) puts(""); } -static void ads_disp_sec_ace_object(struct security_ace_object *object) +static void ads_disp_sec_ace_object(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, struct security_ace_object *object) { if (object->flags & SEC_ACE_OBJECT_PRESENT) { printf("Object type: SEC_ACE_OBJECT_PRESENT\n"); @@ -95,7 +95,7 @@ static void ads_disp_sec_ace_object(struct security_ace_object *object) } /* display ACE */ -static void ads_disp_ace(SEC_ACE *sec_ace) +static void ads_disp_ace(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, SEC_ACE *sec_ace) { const char *access_type = "UNKNOWN"; @@ -132,7 +132,7 @@ static void ads_disp_ace(SEC_ACE *sec_ace) sid_string_static(&sec_ace->trustee), access_type); if (sec_ace_object(sec_ace->type)) { - ads_disp_sec_ace_object(&sec_ace->object.object); + ads_disp_sec_ace_object(ads, mem_ctx, &sec_ace->object.object); } ads_disp_perms(sec_ace->access_mask); @@ -153,7 +153,7 @@ static void ads_disp_acl(SEC_ACL *sec_acl, const char *type) } /* display SD */ -void ads_disp_sd(SEC_DESC *sd) +void ads_disp_sd(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, SEC_DESC *sd) { int i; @@ -165,11 +165,11 @@ void ads_disp_sd(SEC_DESC *sd) ads_disp_acl(sd->sacl, "system"); for (i = 0; i < sd->sacl->num_aces; i ++) - ads_disp_ace(&sd->sacl->aces[i]); + ads_disp_ace(ads, mem_ctx, &sd->sacl->aces[i]); ads_disp_acl(sd->dacl, "user"); for (i = 0; i < sd->dacl->num_aces; i ++) - ads_disp_ace(&sd->dacl->aces[i]); + ads_disp_ace(ads, mem_ctx, &sd->dacl->aces[i]); printf("-------------- End Of Security Descriptor\n"); } diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index a1d1a2d649..32cc82c925 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1837,7 +1837,9 @@ static void dump_sd(ADS_STRUCT *ads, const char *filed, struct berval **values) talloc_destroy(ctx); return; } - if (psd) ads_disp_sd(psd); + if (psd) { + ads_disp_sd(ads, ctx, psd); + } prs_mem_free(&ps); talloc_destroy(ctx); -- cgit From b62ade20d0721c694785fdd2882ea28b129bb0f1 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 11 Jul 2007 13:32:57 +0000 Subject: r23838: Allow to store schema and config path in ADS_STRUCT config. Guenther (This used to be commit 1d5b08326fa72bd3423b377a4e6243466e778622) --- source3/libads/ads_struct.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index b01e0879ef..c66d4e84e8 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -159,6 +159,8 @@ void ads_destroy(ADS_STRUCT **ads) SAFE_FREE((*ads)->config.ldap_server_name); SAFE_FREE((*ads)->config.server_site_name); SAFE_FREE((*ads)->config.client_site_name); + SAFE_FREE((*ads)->config.schema_path); + SAFE_FREE((*ads)->config.config_path); ZERO_STRUCTP(*ads); -- cgit From 34d091f1c6867ac6bc6925fb99dd00724cf3c289 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 11 Jul 2007 13:41:04 +0000 Subject: r23839: Try to get the attribute name from schema GUIDs or the display name from extended rights GUID from ad while dumping the security descriptors's aces. This would perform much better with a guid cache, but for the rare cases where it is used net ads search cn=mymachine ntSecurityDescriptor -U user%pass it should be ok for now. Guenther (This used to be commit b36913433eb74203b29f2b7d412a86e60591ea22) --- source3/libads/disp_sec.c | 53 +++++++++++++++++++++++++++++++++++++++----- source3/libads/ldap_schema.c | 2 +- 2 files changed, 48 insertions(+), 7 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/disp_sec.c b/source3/libads/disp_sec.c index 9ea332858f..4b9a9de23a 100644 --- a/source3/libads/disp_sec.c +++ b/source3/libads/disp_sec.c @@ -80,17 +80,45 @@ static void ads_disp_perms(uint32 type) puts(""); } -static void ads_disp_sec_ace_object(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, struct security_ace_object *object) +static const char *ads_interprete_guid_from_object(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + const struct GUID *guid) +{ + const char *ret = NULL; + + ret = ads_get_attrname_by_guid(ads, ads->config.schema_path, + mem_ctx, guid); + if (ret) { + return talloc_asprintf(mem_ctx, "LDAP attribute: \"%s\"", ret); + } + + ret = ads_get_extended_right_name_by_guid(ads, ads->config.config_path, + mem_ctx, guid); + + if (ret) { + return talloc_asprintf(mem_ctx, "Extended right: \"%s\"", ret); + } + + return ret; +} + +static void ads_disp_sec_ace_object(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + struct security_ace_object *object) { if (object->flags & SEC_ACE_OBJECT_PRESENT) { printf("Object type: SEC_ACE_OBJECT_PRESENT\n"); - printf("Object GUID: %s\n", smb_uuid_string_static( - object->type.type)); + printf("Object GUID: %s (%s)\n", smb_uuid_string_static( + object->type.type), + ads_interprete_guid_from_object(ads, mem_ctx, + &object->type.type)); } if (object->flags & SEC_ACE_OBJECT_INHERITED_PRESENT) { printf("Object type: SEC_ACE_OBJECT_INHERITED_PRESENT\n"); - printf("Object GUID: %s\n", smb_uuid_string_static( - object->inherited_type.inherited_type)); + printf("Object GUID: %s (%s)\n", smb_uuid_string_static( + object->inherited_type.inherited_type), + ads_interprete_guid_from_object(ads, mem_ctx, + &object->inherited_type.inherited_type)); } } @@ -156,7 +184,20 @@ static void ads_disp_acl(SEC_ACL *sec_acl, const char *type) void ads_disp_sd(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, SEC_DESC *sd) { int i; - + char *tmp_path = NULL; + + if (!ads->config.schema_path) { + if (ADS_ERR_OK(ads_schema_path(ads, mem_ctx, &tmp_path))) { + ads->config.schema_path = SMB_STRDUP(tmp_path); + } + } + + if (!ads->config.config_path) { + if (ADS_ERR_OK(ads_config_path(ads, mem_ctx, &tmp_path))) { + ads->config.config_path = SMB_STRDUP(tmp_path); + } + } + printf("-------------- Security Descriptor (revision: %d, type: 0x%02x)\n", sd->revision, sd->type); diff --git a/source3/libads/ldap_schema.c b/source3/libads/ldap_schema.c index 1cdd51faca..170ee65df7 100644 --- a/source3/libads/ldap_schema.c +++ b/source3/libads/ldap_schema.c @@ -195,7 +195,7 @@ failed: /********************************************************************* *********************************************************************/ -static ADS_STATUS ads_schema_path(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char **schema_path) +ADS_STATUS ads_schema_path(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char **schema_path) { ADS_STATUS status; LDAPMessage *res; -- cgit From 8d786a4e2bf23feaeb041f95bb346fbfd0434853 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 11 Jul 2007 15:46:01 +0000 Subject: r23842: Attempt to fix the build with LDAP. Guenther (This used to be commit efd817ae118da51058106ae97854572547e113d3) --- source3/libads/disp_sec.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/disp_sec.c b/source3/libads/disp_sec.c index 4b9a9de23a..135eeffac7 100644 --- a/source3/libads/disp_sec.c +++ b/source3/libads/disp_sec.c @@ -19,6 +19,8 @@ #include "includes.h" +#ifdef HAVE_LDAP + static struct perm_mask_str { uint32 mask; const char *str; @@ -215,4 +217,4 @@ void ads_disp_sd(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, SEC_DESC *sd) printf("-------------- End Of Security Descriptor\n"); } - +#endif -- cgit From ed0ffc5cef4056121f707a1526688ff323445556 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 13 Jul 2007 09:53:55 +0000 Subject: r23861: Fix return code in ads_find_samaccount(). Guenther (This used to be commit 684fcf39dcc08bcf571272549222fdeb11d2725f) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 32cc82c925..84ceba2406 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -3310,7 +3310,7 @@ ADS_STATUS ads_find_samaccount(ADS_STRUCT *ads, } if (ads_count_replies(ads, res) != 1) { - printf("no result\n"); + status = ADS_ERROR(LDAP_NO_RESULTS_RETURNED); goto out; } -- cgit From 28041b6064f3a61c15357eff2baabbe812dcf1f4 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 13 Jul 2007 23:26:55 +0000 Subject: r23869: Protect against partial security descriptors. Guenther (This used to be commit 0a96a11f01dd8c0d29fff1d97c3d666c32b33b59) --- source3/libads/disp_sec.c | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/disp_sec.c b/source3/libads/disp_sec.c index 135eeffac7..e85809635f 100644 --- a/source3/libads/disp_sec.c +++ b/source3/libads/disp_sec.c @@ -88,6 +88,10 @@ static const char *ads_interprete_guid_from_object(ADS_STRUCT *ads, { const char *ret = NULL; + if (!ads || !mem_ctx) { + return NULL; + } + ret = ads_get_attrname_by_guid(ads, ads->config.schema_path, mem_ctx, guid); if (ret) { @@ -188,13 +192,17 @@ void ads_disp_sd(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, SEC_DESC *sd) int i; char *tmp_path = NULL; - if (!ads->config.schema_path) { + if (!sd) { + return; + } + + if (ads && !ads->config.schema_path) { if (ADS_ERR_OK(ads_schema_path(ads, mem_ctx, &tmp_path))) { ads->config.schema_path = SMB_STRDUP(tmp_path); } } - if (!ads->config.config_path) { + if (ads && !ads->config.config_path) { if (ADS_ERR_OK(ads_config_path(ads, mem_ctx, &tmp_path))) { ads->config.config_path = SMB_STRDUP(tmp_path); } @@ -203,16 +211,25 @@ void ads_disp_sd(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, SEC_DESC *sd) printf("-------------- Security Descriptor (revision: %d, type: 0x%02x)\n", sd->revision, sd->type); - printf("owner SID: %s\n", sid_string_static(sd->owner_sid)); - printf("group SID: %s\n", sid_string_static(sd->group_sid)); + + printf("owner SID: %s\n", sd->owner_sid ? + sid_string_static(sd->owner_sid) : "(null)"); + printf("group SID: %s\n", sd->group_sid ? + sid_string_static(sd->group_sid) : "(null)"); ads_disp_acl(sd->sacl, "system"); - for (i = 0; i < sd->sacl->num_aces; i ++) - ads_disp_ace(ads, mem_ctx, &sd->sacl->aces[i]); + if (sd->sacl) { + for (i = 0; i < sd->sacl->num_aces; i ++) { + ads_disp_ace(ads, mem_ctx, &sd->sacl->aces[i]); + } + } ads_disp_acl(sd->dacl, "user"); - for (i = 0; i < sd->dacl->num_aces; i ++) - ads_disp_ace(ads, mem_ctx, &sd->dacl->aces[i]); + if (sd->dacl) { + for (i = 0; i < sd->dacl->num_aces; i ++) { + ads_disp_ace(ads, mem_ctx, &sd->dacl->aces[i]); + } + } printf("-------------- End Of Security Descriptor\n"); } -- cgit From 2fc53c947b6c18f5e9761a26792f806ff588e239 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 16 Jul 2007 09:48:15 +0000 Subject: r23886: add ads_disconnect() function metze (This used to be commit ba70737b7043cae89dd90f8668a24881212ac6fb) --- source3/libads/ads_struct.c | 4 +--- source3/libads/ldap.c | 12 ++++++++++++ source3/libads/ldap_utils.c | 6 +----- 3 files changed, 14 insertions(+), 8 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index c66d4e84e8..c769d8ff48 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -141,9 +141,7 @@ void ads_destroy(ADS_STRUCT **ads) is_mine = (*ads)->is_mine; #if HAVE_LDAP - if ((*ads)->ld) { - ldap_unbind((*ads)->ld); - } + ads_disconnect(*ads); #endif SAFE_FREE((*ads)->server.realm); SAFE_FREE((*ads)->server.workgroup); diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 84ceba2406..c5c43c44c5 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -465,6 +465,18 @@ got_connection: return ads_sasl_bind(ads); } +/** + * Disconnect the LDAP server + * @param ads Pointer to an existing ADS_STRUCT + **/ +void ads_disconnect(ADS_STRUCT *ads) +{ + if (ads->ld) { + ldap_unbind(ads->ld); + ads->ld = NULL; + } +} + /* Duplicate a struct berval into talloc'ed memory */ diff --git a/source3/libads/ldap_utils.c b/source3/libads/ldap_utils.c index 3ad08085bb..16fd32b807 100644 --- a/source3/libads/ldap_utils.c +++ b/source3/libads/ldap_utils.c @@ -75,11 +75,7 @@ static ADS_STATUS ads_do_search_retry_internal(ADS_STRUCT *ads, const char *bind DEBUG(3,("Reopening ads connection to realm '%s' after error %s\n", ads->config.realm, ads_errstr(status))); - if (ads->ld) { - ldap_unbind(ads->ld); - } - - ads->ld = NULL; + ads_disconnect(ads); status = ads_connect(ads); if (!ADS_ERR_OK(status)) { -- cgit From 809c9d4d3136cc46dc228107918ca19d5a008a0a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 16 Jul 2007 11:08:00 +0000 Subject: r23888: move elements belonging to the current ldap connection to a substructure. metze (This used to be commit 00909194a6c1ed193dfdb296f50f58a53450583c) --- source3/libads/ldap.c | 92 +++++++++++++++++++++---------------------- source3/libads/ldap_printer.c | 2 +- source3/libads/ldap_utils.c | 4 +- source3/libads/sasl.c | 12 +++--- 4 files changed, 55 insertions(+), 55 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index c5c43c44c5..c8f68546ad 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -224,8 +224,8 @@ BOOL ads_try_connect(ADS_STRUCT *ads, const char *server ) ads->server.workgroup = SMB_STRDUP(cldap_reply.netbios_domain); - ads->ldap_port = LDAP_PORT; - ads->ldap_ip = *interpret_addr2(srv); + ads->ldap.port = LDAP_PORT; + ads->ldap.ip = *interpret_addr2(srv); SAFE_FREE(srv); /* Store our site name. */ @@ -372,8 +372,8 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) ADS_STATUS status; NTSTATUS ntstatus; - ads->last_attempt = time(NULL); - ads->ld = NULL; + ads->ldap.last_attempt = time(NULL); + ads->ldap.ld = NULL; /* try with a user specified server */ @@ -390,7 +390,7 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) return ADS_ERROR_NT(ntstatus); got_connection: - DEBUG(3,("Connected to LDAP server %s\n", inet_ntoa(ads->ldap_ip))); + DEBUG(3,("Connected to LDAP server %s\n", inet_ntoa(ads->ldap.ip))); if (!ads->auth.user_name) { /* Must use the userPrincipalName value here or sAMAccountName @@ -404,7 +404,7 @@ got_connection: } if (!ads->auth.kdc_server) { - ads->auth.kdc_server = SMB_STRDUP(inet_ntoa(ads->ldap_ip)); + ads->auth.kdc_server = SMB_STRDUP(inet_ntoa(ads->ldap.ip)); } #if KRB5_DNS_HACK @@ -426,7 +426,7 @@ got_connection: /* Otherwise setup the TCP LDAP session */ - if ( (ads->ld = ldap_open_with_timeout(ads->config.ldap_server_name, + if ( (ads->ldap.ld = ldap_open_with_timeout(ads->config.ldap_server_name, LDAP_PORT, lp_ldap_timeout())) == NULL ) { return ADS_ERROR(LDAP_OPERATIONS_ERROR); @@ -434,13 +434,13 @@ got_connection: /* cache the successful connection for workgroup and realm */ if (ads_closest_dc(ads)) { - saf_store( ads->server.workgroup, inet_ntoa(ads->ldap_ip)); - saf_store( ads->server.realm, inet_ntoa(ads->ldap_ip)); + saf_store( ads->server.workgroup, inet_ntoa(ads->ldap.ip)); + saf_store( ads->server.realm, inet_ntoa(ads->ldap.ip)); } - ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); + ldap_set_option(ads->ldap.ld, LDAP_OPT_PROTOCOL_VERSION, &version); - status = ADS_ERROR(smb_ldap_start_tls(ads->ld, version)); + status = ADS_ERROR(smb_ldap_start_tls(ads->ldap.ld, version)); if (!ADS_ERR_OK(status)) { return status; } @@ -455,11 +455,11 @@ got_connection: /* Now do the bind */ if (ads->auth.flags & ADS_AUTH_ANON_BIND) { - return ADS_ERROR(ldap_simple_bind_s( ads->ld, NULL, NULL)); + return ADS_ERROR(ldap_simple_bind_s( ads->ldap.ld, NULL, NULL)); } if (ads->auth.flags & ADS_AUTH_SIMPLE_BIND) { - return ADS_ERROR(ldap_simple_bind_s( ads->ld, ads->auth.user_name, ads->auth.password)); + return ADS_ERROR(ldap_simple_bind_s( ads->ldap.ld, ads->auth.user_name, ads->auth.password)); } return ads_sasl_bind(ads); @@ -471,9 +471,9 @@ got_connection: **/ void ads_disconnect(ADS_STRUCT *ads) { - if (ads->ld) { - ldap_unbind(ads->ld); - ads->ld = NULL; + if (ads->ldap.ld) { + ldap_unbind(ads->ldap.ld); + ads->ldap.ld = NULL; } } @@ -616,7 +616,7 @@ static ADS_STATUS ads_do_paged_search_args(ADS_STRUCT *ads, } /* Paged results only available on ldap v3 or later */ - ldap_get_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); + ldap_get_option(ads->ldap.ld, LDAP_OPT_PROTOCOL_VERSION, &version); if (version < LDAP_VERSION3) { rc = LDAP_NOT_SUPPORTED; goto done; @@ -693,9 +693,9 @@ static ADS_STATUS ads_do_paged_search_args(ADS_STRUCT *ads, leaving this in despite the control that says don't generate referrals, in case the server doesn't support it (jmcd) */ - ldap_set_option(ads->ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF); + ldap_set_option(ads->ldap.ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF); - rc = ldap_search_with_timeout(ads->ld, utf8_path, scope, utf8_expr, + rc = ldap_search_with_timeout(ads->ldap.ld, utf8_path, scope, utf8_expr, search_attrs, 0, controls, NULL, LDAP_NO_LIMIT, (LDAPMessage **)res); @@ -709,7 +709,7 @@ static ADS_STATUS ads_do_paged_search_args(ADS_STRUCT *ads, goto done; } - rc = ldap_parse_result(ads->ld, *res, NULL, NULL, NULL, + rc = ldap_parse_result(ads->ldap.ld, *res, NULL, NULL, NULL, NULL, &rcontrols, 0); if (!rcontrols) { @@ -928,9 +928,9 @@ ADS_STATUS ads_do_search_all_fn(ADS_STRUCT *ads, const char *bind_path, } /* see the note in ads_do_paged_search - we *must* disable referrals */ - ldap_set_option(ads->ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF); + ldap_set_option(ads->ldap.ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF); - rc = ldap_search_with_timeout(ads->ld, utf8_path, scope, utf8_expr, + rc = ldap_search_with_timeout(ads->ldap.ld, utf8_path, scope, utf8_expr, search_attrs, 0, NULL, NULL, LDAP_NO_LIMIT, (LDAPMessage **)res); @@ -1007,7 +1007,7 @@ void ads_memfree(ADS_STRUCT *ads, void *mem) { char *utf8_dn, *unix_dn; - utf8_dn = ldap_get_dn(ads->ld, msg); + utf8_dn = ldap_get_dn(ads->ldap.ld, msg); if (!utf8_dn) { DEBUG (5, ("ads_get_dn: ldap_get_dn failed\n")); @@ -1237,7 +1237,7 @@ ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, ADS_MODLIST mods) for(i=0;(mods[i]!=0)&&(mods[i]!=(LDAPMod *) -1);i++); /* make sure the end of the list is NULL */ mods[i] = NULL; - ret = ldap_modify_ext_s(ads->ld, utf8_dn, + ret = ldap_modify_ext_s(ads->ldap.ld, utf8_dn, (LDAPMod **) mods, controls, NULL); SAFE_FREE(utf8_dn); return ADS_ERROR(ret); @@ -1265,7 +1265,7 @@ ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ADS_MODLIST mods) /* make sure the end of the list is NULL */ mods[i] = NULL; - ret = ldap_add_s(ads->ld, utf8_dn, (LDAPMod**)mods); + ret = ldap_add_s(ads->ldap.ld, utf8_dn, (LDAPMod**)mods); SAFE_FREE(utf8_dn); return ADS_ERROR(ret); } @@ -1285,7 +1285,7 @@ ADS_STATUS ads_del_dn(ADS_STRUCT *ads, char *del_dn) return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); } - ret = ldap_delete_s(ads->ld, utf8_dn); + ret = ldap_delete_s(ads->ldap.ld, utf8_dn); SAFE_FREE(utf8_dn); return ADS_ERROR(ret); } @@ -1765,7 +1765,7 @@ ADS_STATUS ads_move_machine_acct(ADS_STRUCT *ads, const char *machine_name, goto done; } - ldap_status = ldap_rename_s(ads->ld, computer_dn, computer_rdn, + ldap_status = ldap_rename_s(ads->ldap.ld, computer_dn, computer_rdn, org_unit, 1, NULL, NULL); rc = ADS_ERROR(ldap_status); @@ -1952,10 +1952,10 @@ static BOOL ads_dump_field(ADS_STRUCT *ads, char *field, void **values, void *da char *utf8_field; BerElement *b; - for (utf8_field=ldap_first_attribute(ads->ld, + for (utf8_field=ldap_first_attribute(ads->ldap.ld, (LDAPMessage *)msg,&b); utf8_field; - utf8_field=ldap_next_attribute(ads->ld, + utf8_field=ldap_next_attribute(ads->ldap.ld, (LDAPMessage *)msg,b)) { struct berval **ber_vals; char **str_vals, **utf8_vals; @@ -1966,14 +1966,14 @@ static BOOL ads_dump_field(ADS_STRUCT *ads, char *field, void **values, void *da string = fn(ads, field, NULL, data_area); if (string) { - utf8_vals = ldap_get_values(ads->ld, + utf8_vals = ldap_get_values(ads->ldap.ld, (LDAPMessage *)msg, field); str_vals = ads_pull_strvals(ctx, (const char **) utf8_vals); fn(ads, field, (void **) str_vals, data_area); ldap_value_free(utf8_vals); } else { - ber_vals = ldap_get_values_len(ads->ld, + ber_vals = ldap_get_values_len(ads->ldap.ld, (LDAPMessage *)msg, field); fn(ads, field, (void **) ber_vals, data_area); @@ -1997,7 +1997,7 @@ static BOOL ads_dump_field(ADS_STRUCT *ads, char *field, void **values, void *da **/ int ads_count_replies(ADS_STRUCT *ads, void *res) { - return ldap_count_entries(ads->ld, (LDAPMessage *)res); + return ldap_count_entries(ads->ldap.ld, (LDAPMessage *)res); } /** @@ -2008,7 +2008,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) **/ LDAPMessage *ads_first_entry(ADS_STRUCT *ads, LDAPMessage *res) { - return ldap_first_entry(ads->ld, res); + return ldap_first_entry(ads->ldap.ld, res); } /** @@ -2019,7 +2019,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) **/ LDAPMessage *ads_next_entry(ADS_STRUCT *ads, LDAPMessage *res) { - return ldap_next_entry(ads->ld, res); + return ldap_next_entry(ads->ldap.ld, res); } /** @@ -2038,7 +2038,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) char *ux_string; size_t rc; - values = ldap_get_values(ads->ld, msg, field); + values = ldap_get_values(ads->ldap.ld, msg, field); if (!values) return NULL; @@ -2069,7 +2069,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) char **ret = NULL; int i; - values = ldap_get_values(ads->ld, msg, field); + values = ldap_get_values(ads->ldap.ld, msg, field); if (!values) return NULL; @@ -2132,9 +2132,9 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) expected_range_attrib = talloc_asprintf(mem_ctx, "%s;Range=", field); /* look for Range result */ - for (attr = ldap_first_attribute(ads->ld, (LDAPMessage *)msg, &ptr); + for (attr = ldap_first_attribute(ads->ldap.ld, (LDAPMessage *)msg, &ptr); attr; - attr = ldap_next_attribute(ads->ld, (LDAPMessage *)msg, ptr)) { + attr = ldap_next_attribute(ads->ldap.ld, (LDAPMessage *)msg, ptr)) { /* we ignore the fact that this is utf8, as all attributes are ascii... */ if (strnequal(attr, expected_range_attrib, strlen(expected_range_attrib))) { range_attr = attr; @@ -2234,7 +2234,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) { char **values; - values = ldap_get_values(ads->ld, msg, field); + values = ldap_get_values(ads->ldap.ld, msg, field); if (!values) return False; if (!values[0]) { @@ -2259,7 +2259,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) char **values; UUID_FLAT flat_guid; - values = ldap_get_values(ads->ld, msg, "objectGUID"); + values = ldap_get_values(ads->ldap.ld, msg, "objectGUID"); if (!values) return False; @@ -2289,7 +2289,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) struct berval **values; BOOL ret = False; - values = ldap_get_values_len(ads->ld, msg, field); + values = ldap_get_values_len(ads->ldap.ld, msg, field); if (!values) return False; @@ -2317,7 +2317,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) BOOL ret; int count, i; - values = ldap_get_values_len(ads->ld, msg, field); + values = ldap_get_values_len(ads->ldap.ld, msg, field); if (!values) return 0; @@ -2364,7 +2364,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) struct berval **values; BOOL ret = False; - values = ldap_get_values_len(ads->ld, msg, field); + values = ldap_get_values_len(ads->ldap.ld, msg, field); if (!values) return False; @@ -2481,7 +2481,7 @@ ADS_STATUS ads_current_time(ADS_STRUCT *ads) /* establish a new ldap tcp session if necessary */ - if ( !ads->ld ) { + if ( !ads->ldap.ld ) { if ( (ads_s = ads_init( ads->server.realm, ads->server.workgroup, ads->server.ldap_server )) == NULL ) { @@ -2542,7 +2542,7 @@ ADS_STATUS ads_domain_func_level(ADS_STRUCT *ads, uint32 *val) /* establish a new ldap tcp session if necessary */ - if ( !ads->ld ) { + if ( !ads->ldap.ld ) { if ( (ads_s = ads_init( ads->server.realm, ads->server.workgroup, ads->server.ldap_server )) == NULL ) { @@ -3100,7 +3100,7 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) hostnameDN = ads_get_dn(ads, (LDAPMessage *)msg); - rc = ldap_delete_ext_s(ads->ld, hostnameDN, pldap_control, NULL); + rc = ldap_delete_ext_s(ads->ldap.ld, hostnameDN, pldap_control, NULL); if (rc) { DEBUG(3,("ldap_delete_ext_s failed with error code %d\n", rc)); }else { diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index cfddd4cc8a..0c6a280c36 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -43,7 +43,7 @@ if (ads_count_replies(ads, *res) != 1) { return ADS_ERROR(LDAP_NO_SUCH_OBJECT); } - srv_dn = ldap_get_dn(ads->ld, *res); + srv_dn = ldap_get_dn(ads->ldap.ld, *res); if (srv_dn == NULL) { return ADS_ERROR(LDAP_NO_MEMORY); } diff --git a/source3/libads/ldap_utils.c b/source3/libads/ldap_utils.c index 16fd32b807..2f5c11b90c 100644 --- a/source3/libads/ldap_utils.c +++ b/source3/libads/ldap_utils.c @@ -38,8 +38,8 @@ static ADS_STATUS ads_do_search_retry_internal(ADS_STRUCT *ads, const char *bind *res = NULL; - if (!ads->ld && - time(NULL) - ads->last_attempt < ADS_RECONNECT_TIME) { + if (!ads->ldap.ld && + time(NULL) - ads->ldap.last_attempt < ADS_RECONNECT_TIME) { return ADS_ERROR(LDAP_SERVER_DOWN); } diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 9536ba31be..a73545f8e5 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -75,7 +75,7 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) cred.bv_val = (char *)msg1.data; cred.bv_len = msg1.length; scred = NULL; - rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred); + rc = ldap_sasl_bind_s(ads->ldap.ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred); data_blob_free(&msg1); if ((rc != LDAP_SASL_BIND_IN_PROGRESS) && (rc != 0)) { if (scred) { @@ -157,7 +157,7 @@ static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *princip cred.bv_val = (char *)blob.data; cred.bv_len = blob.length; - rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred); + rc = ldap_sasl_bind_s(ads->ldap.ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred); data_blob_free(&blob); data_blob_free(&session_key); @@ -183,7 +183,7 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) BOOL got_kerberos_mechanism = False; #endif - rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", NULL, NULL, NULL, &scred); + rc = ldap_sasl_bind_s(ads->ldap.ld, NULL, "GSS-SPNEGO", NULL, NULL, NULL, &scred); if (rc != LDAP_SASL_BIND_IN_PROGRESS) { status = ADS_ERROR(rc); @@ -397,7 +397,7 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) cred.bv_val = (char *)output_token.value; cred.bv_len = output_token.length; - rc = ldap_sasl_bind_s(ads->ld, NULL, "GSSAPI", &cred, NULL, NULL, + rc = ldap_sasl_bind_s(ads->ldap.ld, NULL, "GSSAPI", &cred, NULL, NULL, &scred); if (rc != LDAP_SASL_BIND_IN_PROGRESS) { status = ADS_ERROR(rc); @@ -471,7 +471,7 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) cred.bv_val = (char *)input_token.value; cred.bv_len = input_token.length; - rc = ldap_sasl_bind_s(ads->ld, NULL, "GSSAPI", &cred, NULL, NULL, + rc = ldap_sasl_bind_s(ads->ldap.ld, NULL, "GSSAPI", &cred, NULL, NULL, &scred); status = ADS_ERROR(rc); @@ -515,7 +515,7 @@ ADS_STATUS ads_sasl_bind(ADS_STRUCT *ads) status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); if (!ADS_ERR_OK(status)) return status; - values = ldap_get_values(ads->ld, res, "supportedSASLMechanisms"); + values = ldap_get_values(ads->ldap.ld, res, "supportedSASLMechanisms"); /* try our supported mechanisms in order */ for (i=0;sasl_mechanisms[i].name;i++) { -- cgit From 57dd25cccbc0691dd4b84d2dca03497863b355ea Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 16 Jul 2007 14:35:33 +0000 Subject: r23893: add dummy callbacks for LDAP SASL wrapping, they're not used yet... metze (This used to be commit a3b97cdce719d9d5e82f26096c0e8c3a86ff3965) --- source3/libads/sasl_wrapping.c | 109 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 source3/libads/sasl_wrapping.c (limited to 'source3/libads') diff --git a/source3/libads/sasl_wrapping.c b/source3/libads/sasl_wrapping.c new file mode 100644 index 0000000000..4bac35fddb --- /dev/null +++ b/source3/libads/sasl_wrapping.c @@ -0,0 +1,109 @@ +/* + Unix SMB/CIFS implementation. + ads sasl wrapping code + Copyright (C) Stefan Metzmacher 2007 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "includes.h" + +#ifdef HAVE_ADS_SASL_WRAPPING + +static int ads_saslwrap_setup(Sockbuf_IO_Desc *sbiod, void *arg) +{ + ADS_STRUCT *ads = (ADS_STRUCT *)arg; + + ads->ldap.sbiod = sbiod; + + sbiod->sbiod_pvt = ads; + + return 0; +} + +static int ads_saslwrap_remove(Sockbuf_IO_Desc *sbiod) +{ + return 0; +} + +static ber_slen_t ads_saslwrap_read(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len) +{ + return LBER_SBIOD_READ_NEXT(sbiod, buf, len); +} + +static ber_slen_t ads_saslwrap_write(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len) +{ + return LBER_SBIOD_WRITE_NEXT(sbiod, buf, len); +} + + +static int ads_saslwrap_ctrl(Sockbuf_IO_Desc *sbiod, int opt, void *arg) +{ + return LBER_SBIOD_CTRL_NEXT(sbiod, opt, arg); +} + +static int ads_saslwrap_close(Sockbuf_IO_Desc *sbiod) +{ + return 0; +} + +static const Sockbuf_IO ads_saslwrap_sockbuf_io = { + ads_saslwrap_setup, /* sbi_setup */ + ads_saslwrap_remove, /* sbi_remove */ + ads_saslwrap_ctrl, /* sbi_ctrl */ + ads_saslwrap_read, /* sbi_read */ + ads_saslwrap_write, /* sbi_write */ + ads_saslwrap_close /* sbi_close */ +}; + +ADS_STATUS ads_setup_sasl_wrapping(ADS_STRUCT *ads) +{ + ADS_STATUS status; + Sockbuf *sb; + Sockbuf_IO *io = discard_const_p(Sockbuf_IO, &ads_saslwrap_sockbuf_io); + int rc; + + rc = ldap_get_option(ads->ldap.ld, LDAP_OPT_SOCKBUF, &sb); + status = ADS_ERROR_LDAP(rc); + if (!ADS_ERR_OK(status)) { + return status; + } + + /* debugging for the layer above SASL */ + rc = ber_sockbuf_add_io(sb, io, LBER_SBIOD_LEVEL_TRANSPORT, + (void *)"ads_sasl_wrapping_above" ); + status = ADS_ERROR_LDAP(rc); + if (!ADS_ERR_OK(status)) { + return status; + } + + /* setup the real wrapping callbacks */ + rc = ber_sockbuf_add_io(sb, io, LBER_SBIOD_LEVEL_TRANSPORT, ads); + status = ADS_ERROR_LDAP(rc); + if (!ADS_ERR_OK(status)) { + return status; + } + + /* debugging for the layer below SASL */ + rc = ber_sockbuf_add_io(sb, io, LBER_SBIOD_LEVEL_TRANSPORT, + (void *)"ads_sasl_wrapping_below" ); + status = ADS_ERROR_LDAP(rc); + if (!ADS_ERR_OK(status)) { + return status; + } + + return ADS_SUCCESS; +} + +#endif /* HAVE_ADS_SASL_WRAPPING */ -- cgit From 77619f37a02da09a77f3fac4cb86df5e40839b2a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 16 Jul 2007 16:08:24 +0000 Subject: r23898: rename HAVE_ADS_SASL_WRAPPING -> HAVE_LDAP_SASL_WRAPPING metze (This used to be commit 873eaff8febb50f00f9dac64c57b2a22c16f4f9b) --- source3/libads/sasl_wrapping.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/sasl_wrapping.c b/source3/libads/sasl_wrapping.c index 4bac35fddb..5afa3eef15 100644 --- a/source3/libads/sasl_wrapping.c +++ b/source3/libads/sasl_wrapping.c @@ -19,7 +19,7 @@ #include "includes.h" -#ifdef HAVE_ADS_SASL_WRAPPING +#ifdef HAVE_LDAP_SASL_WRAPPING static int ads_saslwrap_setup(Sockbuf_IO_Desc *sbiod, void *arg) { @@ -106,4 +106,4 @@ ADS_STATUS ads_setup_sasl_wrapping(ADS_STRUCT *ads) return ADS_SUCCESS; } -#endif /* HAVE_ADS_SASL_WRAPPING */ +#endif /* HAVE_LDAP_SASL_WRAPPING */ -- cgit From d48dbc8bad3b3b3eae4a82ae2b1d609d086f4cc8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 17 Jul 2007 07:28:00 +0000 Subject: r23916: use the correct io operations for debugging metze (This used to be commit d745a1a71991f306c29b3c62f43d619177f79725) --- source3/libads/sasl_wrapping.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/sasl_wrapping.c b/source3/libads/sasl_wrapping.c index 5afa3eef15..1160493902 100644 --- a/source3/libads/sasl_wrapping.c +++ b/source3/libads/sasl_wrapping.c @@ -81,8 +81,9 @@ ADS_STATUS ads_setup_sasl_wrapping(ADS_STRUCT *ads) } /* debugging for the layer above SASL */ - rc = ber_sockbuf_add_io(sb, io, LBER_SBIOD_LEVEL_TRANSPORT, - (void *)"ads_sasl_wrapping_above" ); + rc = ber_sockbuf_add_io(sb, &ber_sockbuf_io_debug, + LBER_SBIOD_LEVEL_TRANSPORT, + (void *)"ads_sasl_wrapping_above"); status = ADS_ERROR_LDAP(rc); if (!ADS_ERR_OK(status)) { return status; @@ -96,8 +97,9 @@ ADS_STATUS ads_setup_sasl_wrapping(ADS_STRUCT *ads) } /* debugging for the layer below SASL */ - rc = ber_sockbuf_add_io(sb, io, LBER_SBIOD_LEVEL_TRANSPORT, - (void *)"ads_sasl_wrapping_below" ); + rc = ber_sockbuf_add_io(sb, &ber_sockbuf_io_debug, + LBER_SBIOD_LEVEL_TRANSPORT, + (void *)"ads_sasl_wrapping_below"); status = ADS_ERROR_LDAP(rc); if (!ADS_ERR_OK(status)) { return status; -- cgit From 8cd89a20cea949485d9f54ad17ea0590a2380ca5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 17 Jul 2007 07:29:43 +0000 Subject: r23918: not all ldap libraries support debugging metze (This used to be commit 3f68189c9a319ac9cae76f6d2b586cbde6d31e3c) --- source3/libads/sasl_wrapping.c | 18 ------------------ 1 file changed, 18 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/sasl_wrapping.c b/source3/libads/sasl_wrapping.c index 1160493902..4a26afe740 100644 --- a/source3/libads/sasl_wrapping.c +++ b/source3/libads/sasl_wrapping.c @@ -80,15 +80,6 @@ ADS_STATUS ads_setup_sasl_wrapping(ADS_STRUCT *ads) return status; } - /* debugging for the layer above SASL */ - rc = ber_sockbuf_add_io(sb, &ber_sockbuf_io_debug, - LBER_SBIOD_LEVEL_TRANSPORT, - (void *)"ads_sasl_wrapping_above"); - status = ADS_ERROR_LDAP(rc); - if (!ADS_ERR_OK(status)) { - return status; - } - /* setup the real wrapping callbacks */ rc = ber_sockbuf_add_io(sb, io, LBER_SBIOD_LEVEL_TRANSPORT, ads); status = ADS_ERROR_LDAP(rc); @@ -96,15 +87,6 @@ ADS_STATUS ads_setup_sasl_wrapping(ADS_STRUCT *ads) return status; } - /* debugging for the layer below SASL */ - rc = ber_sockbuf_add_io(sb, &ber_sockbuf_io_debug, - LBER_SBIOD_LEVEL_TRANSPORT, - (void *)"ads_sasl_wrapping_below"); - status = ADS_ERROR_LDAP(rc); - if (!ADS_ERR_OK(status)) { - return status; - } - return ADS_SUCCESS; } -- cgit From 7bef162aeb74afd654b8e802bdf81b220ceb44b4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 17 Jul 2007 10:13:53 +0000 Subject: r23922: implement input buffer handling for the SASL read wrapper metze (This used to be commit 7d8518ebd9470062b499b7074a940e14520e99f2) --- source3/libads/sasl_wrapping.c | 131 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 129 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/sasl_wrapping.c b/source3/libads/sasl_wrapping.c index 4a26afe740..9617961969 100644 --- a/source3/libads/sasl_wrapping.c +++ b/source3/libads/sasl_wrapping.c @@ -37,9 +37,137 @@ static int ads_saslwrap_remove(Sockbuf_IO_Desc *sbiod) return 0; } +static ber_slen_t ads_saslwrap_prepare_inbuf(ADS_STRUCT *ads) +{ + ads->ldap.in.ofs = 0; + ads->ldap.in.needed = 0; + ads->ldap.in.left = 0; + ads->ldap.in.size = 4 + ads->ldap.in.min; + ads->ldap.in.buf = talloc_array(ads->ldap.mem_ctx, + uint8, ads->ldap.in.size); + if (!ads->ldap.in.buf) { + return -1; + } + + return 0; +} + +static ber_slen_t ads_saslwrap_grow_inbuf(ADS_STRUCT *ads) +{ + if (ads->ldap.in.size == (4 + ads->ldap.in.needed)) { + return 0; + } + + ads->ldap.in.size = 4 + ads->ldap.in.needed; + ads->ldap.in.buf = talloc_realloc(ads->ldap.mem_ctx, + ads->ldap.in.buf, + uint8, ads->ldap.in.size); + if (!ads->ldap.in.buf) { + return -1; + } + + return 0; +} + +static void ads_saslwrap_shrink_inbuf(ADS_STRUCT *ads) +{ + talloc_free(ads->ldap.in.buf); + + ads->ldap.in.buf = NULL; + ads->ldap.in.size = 0; + ads->ldap.in.ofs = 0; + ads->ldap.in.needed = 0; + ads->ldap.in.left = 0; +} + static ber_slen_t ads_saslwrap_read(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len) { - return LBER_SBIOD_READ_NEXT(sbiod, buf, len); + ADS_STRUCT *ads = (ADS_STRUCT *)sbiod->sbiod_pvt; + ber_slen_t ret; + + /* If ofs < 4 it means we don't have read the length header yet */ + if (ads->ldap.in.ofs < 4) { + ret = ads_saslwrap_prepare_inbuf(ads); + if (ret < 0) return ret; + + ret = LBER_SBIOD_READ_NEXT(sbiod, + ads->ldap.in.buf + ads->ldap.in.ofs, + 4 - ads->ldap.in.ofs); + if (ret < 0) return ret; + ads->ldap.in.ofs += ret; + + if (ads->ldap.in.ofs < 4) goto eagain; + + ads->ldap.in.needed = RIVAL(ads->ldap.in.buf, 4); + if (ads->ldap.in.needed > ads->ldap.in.max) { + errno = EINVAL; + return -1; + } + if (ads->ldap.in.needed < ads->ldap.in.min) { + errno = EINVAL; + return -1; + } + + ret = ads_saslwrap_grow_inbuf(ads); + if (ret < 0) return ret; + } + + /* + * if there's more data needed from the remote end, + * we need to read more + */ + if (ads->ldap.in.needed > 0) { + ret = LBER_SBIOD_READ_NEXT(sbiod, + ads->ldap.in.buf + ads->ldap.in.ofs, + ads->ldap.in.needed); + if (ret < 0) return ret; + ads->ldap.in.ofs += ret; + ads->ldap.in.needed -= ret; + + if (ads->ldap.in.needed > 0) goto eagain; + } + + /* + * if we have a complete packet and have not yet unwrapped it + * we need to call the mech specific unwrap() hook + */ + if (ads->ldap.in.needed == 0 && ads->ldap.in.left == 0) { + ADS_STATUS status; + status = ads->ldap.wrap_ops->unwrap(ads); + if (!ADS_ERR_OK(status)) { + errno = EACCES; + return -1; + } + } + + /* + * if we have unwrapped data give it to the caller + */ + if (ads->ldap.in.left > 0) { + ret = MIN(ads->ldap.in.left, len); + memcpy(buf, ads->ldap.in.buf + ads->ldap.in.ofs, ret); + ads->ldap.in.ofs += ret; + ads->ldap.in.left -= ret; + + /* + * if no more is left shrink the inbuf, + * this will trigger reading a new SASL packet + * from the remote stream in the next call + */ + if (ads->ldap.in.left == 0) { + ads_saslwrap_shrink_inbuf(ads); + } + + return ret; + } + + /* + * if we don't have anything for the caller yet, + * tell him to ask again + */ +eagain: + errno = EAGAIN; + return -1; } static ber_slen_t ads_saslwrap_write(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len) @@ -47,7 +175,6 @@ static ber_slen_t ads_saslwrap_write(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_ return LBER_SBIOD_WRITE_NEXT(sbiod, buf, len); } - static int ads_saslwrap_ctrl(Sockbuf_IO_Desc *sbiod, int opt, void *arg) { return LBER_SBIOD_CTRL_NEXT(sbiod, opt, arg); -- cgit From 307e51ed1420fcf9e91e8ac7c0a1689e13f3edec Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 17 Jul 2007 11:14:42 +0000 Subject: r23926: implement output buffer handling for the SASL write wrapper metze (This used to be commit 65ce6fa21adec704b3cde30c57001e5620f048e4) --- source3/libads/sasl_wrapping.c | 68 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/sasl_wrapping.c b/source3/libads/sasl_wrapping.c index 9617961969..419557a7bb 100644 --- a/source3/libads/sasl_wrapping.c +++ b/source3/libads/sasl_wrapping.c @@ -170,9 +170,75 @@ eagain: return -1; } +static ber_slen_t ads_saslwrap_prepare_outbuf(ADS_STRUCT *ads, uint32 len) +{ + ads->ldap.out.ofs = 4; + ads->ldap.out.left = 4; + ads->ldap.out.size = 4 + ads->ldap.out.sig_size + len; + ads->ldap.out.buf = talloc_array(ads->ldap.mem_ctx, + uint8, ads->ldap.out.size); + if (!ads->ldap.out.buf) { + return -1; + } + + return 0; +} + +static void ads_saslwrap_shrink_outbuf(ADS_STRUCT *ads) +{ + talloc_free(ads->ldap.out.buf); + + ads->ldap.out.buf = NULL; + ads->ldap.out.size = 0; + ads->ldap.out.ofs = 0; + ads->ldap.out.left = 0; +} + static ber_slen_t ads_saslwrap_write(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len) { - return LBER_SBIOD_WRITE_NEXT(sbiod, buf, len); + ADS_STRUCT *ads = (ADS_STRUCT *)sbiod->sbiod_pvt; + ber_slen_t ret, rlen; + + /* if the buffer is empty, we need to wrap in incoming buffer */ + if (ads->ldap.out.left == 0) { + ADS_STATUS status; + + if (len == 0) { + errno = EINVAL; + return -1; + } + + rlen = MIN(len, ads->ldap.out.max); + + ret = ads_saslwrap_prepare_outbuf(ads, rlen); + if (ret < 0) return ret; + + status = ads->ldap.wrap_ops->wrap(ads, buf, rlen); + if (!ADS_ERR_OK(status)) { + errno = EACCES; + return -1; + } + + RSIVAL(ads->ldap.out.buf, 0, ads->ldap.out.size - 4); + } else { + rlen = -1; + } + + ret = LBER_SBIOD_WRITE_NEXT(sbiod, + ads->ldap.out.buf + ads->ldap.out.ofs, + ads->ldap.out.left); + if (ret < 0) return ret; + ads->ldap.out.ofs += ret; + ads->ldap.out.left -= ret; + + if (ads->ldap.out.left == 0) { + ads_saslwrap_shrink_outbuf(ads); + } + + if (rlen > 0) return rlen; + + errno = EAGAIN; + return -1; } static int ads_saslwrap_ctrl(Sockbuf_IO_Desc *sbiod, int opt, void *arg) -- cgit From 00b27d2d6933e29d9d89652e4f193562bb204f39 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 17 Jul 2007 14:08:53 +0000 Subject: r23933: - implement ctrl SASL wrapping hook - pass down sign or seal hooks - some sasl wrapping fixes metze (This used to be commit 8c64ca3394489b28034310fe64d6998e49827196) --- source3/libads/sasl_wrapping.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/sasl_wrapping.c b/source3/libads/sasl_wrapping.c index 419557a7bb..77a71d8e96 100644 --- a/source3/libads/sasl_wrapping.c +++ b/source3/libads/sasl_wrapping.c @@ -98,7 +98,7 @@ static ber_slen_t ads_saslwrap_read(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t if (ads->ldap.in.ofs < 4) goto eagain; - ads->ldap.in.needed = RIVAL(ads->ldap.in.buf, 4); + ads->ldap.in.needed = RIVAL(ads->ldap.in.buf, 0); if (ads->ldap.in.needed > ads->ldap.in.max) { errno = EINVAL; return -1; @@ -172,8 +172,8 @@ eagain: static ber_slen_t ads_saslwrap_prepare_outbuf(ADS_STRUCT *ads, uint32 len) { - ads->ldap.out.ofs = 4; - ads->ldap.out.left = 4; + ads->ldap.out.ofs = 0; + ads->ldap.out.left = 0; ads->ldap.out.size = 4 + ads->ldap.out.sig_size + len; ads->ldap.out.buf = talloc_array(ads->ldap.mem_ctx, uint8, ads->ldap.out.size); @@ -219,7 +219,7 @@ static ber_slen_t ads_saslwrap_write(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_ return -1; } - RSIVAL(ads->ldap.out.buf, 0, ads->ldap.out.size - 4); + RSIVAL(ads->ldap.out.buf, 0, ads->ldap.out.left - 4); } else { rlen = -1; } @@ -243,7 +243,22 @@ static ber_slen_t ads_saslwrap_write(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_ static int ads_saslwrap_ctrl(Sockbuf_IO_Desc *sbiod, int opt, void *arg) { - return LBER_SBIOD_CTRL_NEXT(sbiod, opt, arg); + ADS_STRUCT *ads = (ADS_STRUCT *)sbiod->sbiod_pvt; + int ret; + + switch (opt) { + case LBER_SB_OPT_DATA_READY: + if (ads->ldap.in.left > 0) { + return 1; + } + ret = LBER_SBIOD_CTRL_NEXT(sbiod, opt, arg); + break; + default: + ret = LBER_SBIOD_CTRL_NEXT(sbiod, opt, arg); + break; + } + + return ret; } static int ads_saslwrap_close(Sockbuf_IO_Desc *sbiod) @@ -260,7 +275,9 @@ static const Sockbuf_IO ads_saslwrap_sockbuf_io = { ads_saslwrap_close /* sbi_close */ }; -ADS_STATUS ads_setup_sasl_wrapping(ADS_STRUCT *ads) +ADS_STATUS ads_setup_sasl_wrapping(ADS_STRUCT *ads, + const struct ads_saslwrap_ops *ops, + void *private_data) { ADS_STATUS status; Sockbuf *sb; @@ -280,6 +297,9 @@ ADS_STATUS ads_setup_sasl_wrapping(ADS_STRUCT *ads) return status; } + ads->ldap.wrap_ops = ops; + ads->ldap.wrap_private_data = private_data; + return ADS_SUCCESS; } -- cgit From 9e0c550922e44dacc57480a96dd217bc6ab28459 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 17 Jul 2007 20:28:31 +0000 Subject: r23937: Use ads_config_path() when we need to know the configration context. Guenther (This used to be commit 1a62c731c6259bf4285d3735bff8b191002553f7) --- source3/libads/ldap.c | 37 +++++++++++-------------------------- 1 file changed, 11 insertions(+), 26 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index c8f68546ad..fe7add5e75 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2662,8 +2662,8 @@ ADS_STATUS ads_site_dn_for_machine(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const c { ADS_STATUS status; LDAPMessage *res; - const char *parent, *config_context, *filter; - const char *attrs[] = { "configurationNamingContext", NULL }; + const char *parent, *filter; + char *config_context = NULL; char *dn; /* shortcut a query */ @@ -2671,26 +2671,18 @@ ADS_STATUS ads_site_dn_for_machine(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const c return ads_site_dn(ads, mem_ctx, site_dn); } - status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); + status = ads_config_path(ads, mem_ctx, &config_context); if (!ADS_ERR_OK(status)) { return status; } - config_context = ads_pull_string(ads, mem_ctx, res, "configurationNamingContext"); - if (config_context == NULL) { - ads_msgfree(ads, res); - return ADS_ERROR(LDAP_NO_MEMORY); - } - filter = talloc_asprintf(mem_ctx, "(cn=%s)", computer_name); if (filter == NULL) { - ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_MEMORY); } - ads_msgfree(ads, res); - - status = ads_do_search(ads, config_context, LDAP_SCOPE_SUBTREE, filter, NULL, &res); + status = ads_do_search(ads, config_context, LDAP_SCOPE_SUBTREE, + filter, NULL, &res); if (!ADS_ERR_OK(status)) { return status; } @@ -2739,34 +2731,27 @@ ADS_STATUS ads_upn_suffixes(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char ***suffix { ADS_STATUS status; LDAPMessage *res; - const char *config_context, *base; - const char *attrs[] = { "configurationNamingContext", NULL }; - const char *attrs2[] = { "uPNSuffixes", NULL }; + const char *base; + char *config_context = NULL; + const char *attrs[] = { "uPNSuffixes", NULL }; - status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); + status = ads_config_path(ads, mem_ctx, &config_context); if (!ADS_ERR_OK(status)) { return status; } - config_context = ads_pull_string(ads, mem_ctx, res, "configurationNamingContext"); - if (config_context == NULL) { - ads_msgfree(ads, res); - return ADS_ERROR(LDAP_NO_MEMORY); - } - - ads_msgfree(ads, res); - base = talloc_asprintf(mem_ctx, "cn=Partitions,%s", config_context); if (base == NULL) { return ADS_ERROR(LDAP_NO_MEMORY); } - status = ads_search_dn(ads, &res, base, attrs2); + status = ads_search_dn(ads, &res, base, attrs); if (!ADS_ERR_OK(status)) { return status; } if (ads_count_replies(ads, res) != 1) { + ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_SUCH_OBJECT); } -- cgit From e0c4034393a05acba9b6ba7dd015cfc3e6d46c0f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 18 Jul 2007 07:30:41 +0000 Subject: r23943: - always provide ads_setup_sasl_wrapping() function - read/write returning 0 means EOF and we need to return direct metze (This used to be commit 885d557ae746c318df0aabc0a03dce1587918cce) --- source3/libads/sasl_wrapping.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/sasl_wrapping.c b/source3/libads/sasl_wrapping.c index 77a71d8e96..931273f40c 100644 --- a/source3/libads/sasl_wrapping.c +++ b/source3/libads/sasl_wrapping.c @@ -93,7 +93,7 @@ static ber_slen_t ads_saslwrap_read(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t ret = LBER_SBIOD_READ_NEXT(sbiod, ads->ldap.in.buf + ads->ldap.in.ofs, 4 - ads->ldap.in.ofs); - if (ret < 0) return ret; + if (ret <= 0) return ret; ads->ldap.in.ofs += ret; if (ads->ldap.in.ofs < 4) goto eagain; @@ -120,7 +120,7 @@ static ber_slen_t ads_saslwrap_read(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t ret = LBER_SBIOD_READ_NEXT(sbiod, ads->ldap.in.buf + ads->ldap.in.ofs, ads->ldap.in.needed); - if (ret < 0) return ret; + if (ret <= 0) return ret; ads->ldap.in.ofs += ret; ads->ldap.in.needed -= ret; @@ -227,7 +227,7 @@ static ber_slen_t ads_saslwrap_write(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_ ret = LBER_SBIOD_WRITE_NEXT(sbiod, ads->ldap.out.buf + ads->ldap.out.ofs, ads->ldap.out.left); - if (ret < 0) return ret; + if (ret <= 0) return ret; ads->ldap.out.ofs += ret; ads->ldap.out.left -= ret; @@ -302,5 +302,11 @@ ADS_STATUS ads_setup_sasl_wrapping(ADS_STRUCT *ads, return ADS_SUCCESS; } - +#else +ADS_STATUS ads_setup_sasl_wrapping(ADS_STRUCT *ads, + const struct ads_saslwrap_ops *ops, + void *private_data) +{ + return ADS_ERROR_NT(NT_STATUS_NOT_SUPPORTED); +} #endif /* HAVE_LDAP_SASL_WRAPPING */ -- cgit From 07c034f7c443689749c2b4b138acb991da575c3a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 18 Jul 2007 07:45:16 +0000 Subject: r23945: add infrastructure to select plain, sign or seal LDAP connection metze (This used to be commit 2075c05b3d8baa7d6d8510cd962471a5781740a6) --- source3/libads/ldap.c | 17 +++++++++++++++-- source3/libads/sasl.c | 8 ++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index fe7add5e75..0b73229736 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -372,8 +372,9 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) ADS_STATUS status; NTSTATUS ntstatus; - ads->ldap.last_attempt = time(NULL); - ads->ldap.ld = NULL; + ZERO_STRUCT(ads->ldap); + ads->ldap.last_attempt = time(NULL); + ads->ldap.wrap_type = ADS_SASLWRAP_TYPE_PLAIN; /* try with a user specified server */ @@ -423,6 +424,11 @@ got_connection: if (ads->auth.flags & ADS_AUTH_NO_BIND) { return ADS_SUCCESS; } + + ads->ldap.mem_ctx = talloc_new("ads LDAP connection memory"); + if (!ads->ldap.mem_ctx) { + return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + } /* Otherwise setup the TCP LDAP session */ @@ -475,6 +481,13 @@ void ads_disconnect(ADS_STRUCT *ads) ldap_unbind(ads->ldap.ld); ads->ldap.ld = NULL; } + if (ads->ldap.wrap_ops && ads->ldap.wrap_ops->disconnect) { + ads->ldap.wrap_ops->disconnect(ads); + } + if (ads->ldap.mem_ctx) { + talloc_free(ads->ldap.mem_ctx); + } + ZERO_STRUCT(ads->ldap); } /* diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index a73545f8e5..94600d7234 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -517,6 +517,14 @@ ADS_STATUS ads_sasl_bind(ADS_STRUCT *ads) values = ldap_get_values(ads->ldap.ld, res, "supportedSASLMechanisms"); + if (ads->auth.flags & ADS_AUTH_SASL_SEAL) { + ads->ldap.wrap_type = ADS_SASLWRAP_TYPE_SEAL; + } else if (ads->auth.flags & ADS_AUTH_SASL_SIGN) { + ads->ldap.wrap_type = ADS_SASLWRAP_TYPE_SIGN; + } else { + ads->ldap.wrap_type = ADS_SASLWRAP_TYPE_PLAIN; + } + /* try our supported mechanisms in order */ for (i=0;sasl_mechanisms[i].name;i++) { /* see if the server supports it */ -- cgit From ea3c3b9272e6f90b93e11d898250627009f1abd1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 18 Jul 2007 08:15:42 +0000 Subject: r23946: add support for NTLMSSP sign and seal NOTE: windows servers are broken with sign only... metze (This used to be commit 408bb2e6e2171196a2bd314db181d9b124e931a1) --- source3/libads/sasl.c | 123 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 122 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 94600d7234..08a6765e27 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -21,6 +21,95 @@ #ifdef HAVE_LDAP +static ADS_STATUS ads_sasl_ntlmssp_wrap(ADS_STRUCT *ads, uint8 *buf, uint32 len) +{ + struct ntlmssp_state *ntlmssp_state = ads->ldap.wrap_private_data; + ADS_STATUS status; + NTSTATUS nt_status; + DATA_BLOB sig; + uint8 *dptr = ads->ldap.out.buf + (4 + NTLMSSP_SIG_SIZE); + + /* copy the data to the right location */ + memcpy(dptr, buf, len); + + /* create the signature and may encrypt the data */ + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL) { + nt_status = ntlmssp_seal_packet(ntlmssp_state, + dptr, len, + dptr, len, + &sig); + } else { + nt_status = ntlmssp_sign_packet(ntlmssp_state, + dptr, len, + dptr, len, + &sig); + } + status = ADS_ERROR_NT(nt_status); + if (!ADS_ERR_OK(status)) return status; + + /* copy the signature to the right location */ + memcpy(ads->ldap.out.buf + 4, + sig.data, NTLMSSP_SIG_SIZE); + + data_blob_free(&sig); + + /* set how many bytes must be written to the underlying socket */ + ads->ldap.out.left = 4 + NTLMSSP_SIG_SIZE + len; + + return ADS_SUCCESS; +} + +static ADS_STATUS ads_sasl_ntlmssp_unwrap(ADS_STRUCT *ads) +{ + struct ntlmssp_state *ntlmssp_state = ads->ldap.wrap_private_data; + ADS_STATUS status; + NTSTATUS nt_status; + DATA_BLOB sig; + uint8 *dptr = ads->ldap.in.buf + (4 + NTLMSSP_SIG_SIZE); + uint32 dlen = ads->ldap.in.ofs - (4 + NTLMSSP_SIG_SIZE); + + /* wrap the signature into a DATA_BLOB */ + sig = data_blob_const(ads->ldap.in.buf + 4, NTLMSSP_SIG_SIZE); + + /* verify the signature and maybe decrypt the data */ + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL) { + nt_status = ntlmssp_unseal_packet(ntlmssp_state, + dptr, dlen, + dptr, dlen, + &sig); + } else { + nt_status = ntlmssp_check_packet(ntlmssp_state, + dptr, dlen, + dptr, dlen, + &sig); + } + status = ADS_ERROR_NT(nt_status); + if (!ADS_ERR_OK(status)) return status; + + /* set the amount of bytes for the upper layer and set the ofs to the data */ + ads->ldap.in.left = dlen; + ads->ldap.in.ofs = 4 + NTLMSSP_SIG_SIZE; + + return ADS_SUCCESS; +} + +static void ads_sasl_ntlmssp_disconnect(ADS_STRUCT *ads) +{ + struct ntlmssp_state *ntlmssp_state = ads->ldap.wrap_private_data; + + ntlmssp_end(&ntlmssp_state); + + ads->ldap.wrap_ops = NULL; + ads->ldap.wrap_private_data = NULL; +} + +static const struct ads_saslwrap_ops ads_sasl_ntlmssp_ops = { + .name = "ntlmssp", + .wrap = ads_sasl_ntlmssp_wrap, + .unwrap = ads_sasl_ntlmssp_unwrap, + .disconnect = ads_sasl_ntlmssp_disconnect +}; + /* perform a LDAP/SASL/SPNEGO/NTLMSSP bind (just how many layers can we fit on one socket??) @@ -35,6 +124,7 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) int rc; NTSTATUS nt_status; int turn = 1; + uint32 features = 0; struct ntlmssp_state *ntlmssp_state; @@ -53,6 +143,28 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) return ADS_ERROR_NT(nt_status); } + switch (ads->ldap.wrap_type) { + case ADS_SASLWRAP_TYPE_SEAL: + features = NTLMSSP_FEATURE_SIGN | NTLMSSP_FEATURE_SEAL; + break; + case ADS_SASLWRAP_TYPE_SIGN: + if (ads->auth.flags & ADS_AUTH_SASL_FORCE) { + features = NTLMSSP_FEATURE_SIGN; + } else { + /* + * windows servers are broken with sign only, + * so we need to use seal here too + */ + features = NTLMSSP_FEATURE_SIGN | NTLMSSP_FEATURE_SEAL; + ads->ldap.wrap_type = ADS_SASLWRAP_TYPE_SEAL; + } + break; + case ADS_SASLWRAP_TYPE_PLAIN: + break; + } + + ntlmssp_want_feature(ntlmssp_state, features); + blob_in = data_blob_null; do { @@ -130,7 +242,16 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) /* we have a reference conter on ntlmssp_state, if we are signing then the state will be kept by the signing engine */ - ntlmssp_end(&ntlmssp_state); + if (ads->ldap.wrap_type > ADS_SASLWRAP_TYPE_PLAIN) { + ads->ldap.out.min = 4; + ads->ldap.out.max = 0x0FFFFFFF - NTLMSSP_SIG_SIZE; + ads->ldap.out.sig_size = NTLMSSP_SIG_SIZE; + ads->ldap.in.min = 4; + ads->ldap.in.max = 0x0FFFFFFF; + ads_setup_sasl_wrapping(ads, &ads_sasl_ntlmssp_ops, ntlmssp_state); + } else { + ntlmssp_end(&ntlmssp_state); + } return ADS_ERROR(rc); } -- cgit From 14e81b300901a764d3c400d35991b04ad3d6a89c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 18 Jul 2007 08:19:13 +0000 Subject: r23948: add gsskrb5 sign and seal support for LDAP connections NOTE: only for the "GSSAPI" SASL mech yet metze (This used to be commit a079b66384b15e9d569dded0d9d6bd830e1a6dfa) --- source3/libads/sasl.c | 140 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 135 insertions(+), 5 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 08a6765e27..f423464a07 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -256,6 +256,105 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) return ADS_ERROR(rc); } +#ifdef HAVE_GSSAPI +static ADS_STATUS ads_sasl_gssapi_wrap(ADS_STRUCT *ads, uint8 *buf, uint32 len) +{ + gss_ctx_id_t context_handle = ads->ldap.wrap_private_data; + ADS_STATUS status; + int gss_rc; + uint32 minor_status; + gss_buffer_desc unwrapped, wrapped; + int conf_req_flag, conf_state; + + unwrapped.value = buf; + unwrapped.length = len; + + /* for now request sign and seal */ + conf_req_flag = (ads->ldap.wrap_type == ADS_SASLWRAP_TYPE_SEAL); + + gss_rc = gss_wrap(&minor_status, context_handle, + conf_req_flag, GSS_C_QOP_DEFAULT, + &unwrapped, &conf_state, + &wrapped); + status = ADS_ERROR_GSS(gss_rc, minor_status); + if (!ADS_ERR_OK(status)) return status; + + if (conf_req_flag && conf_state == 0) { + return ADS_ERROR_NT(NT_STATUS_ACCESS_DENIED); + } + + if ((ads->ldap.out.size - 4) < wrapped.length) { + return ADS_ERROR_NT(NT_STATUS_INTERNAL_ERROR); + } + + /* copy the wrapped blob to the right location */ + memcpy(ads->ldap.out.buf + 4, wrapped.value, wrapped.length); + + /* set how many bytes must be written to the underlying socket */ + ads->ldap.out.left = 4 + wrapped.length; + + gss_release_buffer(&minor_status, &wrapped); + + return ADS_SUCCESS; +} + +static ADS_STATUS ads_sasl_gssapi_unwrap(ADS_STRUCT *ads) +{ + gss_ctx_id_t context_handle = ads->ldap.wrap_private_data; + ADS_STATUS status; + int gss_rc; + uint32 minor_status; + gss_buffer_desc unwrapped, wrapped; + int conf_state; + + wrapped.value = ads->ldap.in.buf + 4; + wrapped.length = ads->ldap.in.ofs - 4; + + gss_rc = gss_unwrap(&minor_status, context_handle, + &wrapped, &unwrapped, + &conf_state, GSS_C_QOP_DEFAULT); + status = ADS_ERROR_GSS(gss_rc, minor_status); + if (!ADS_ERR_OK(status)) return status; + + if (ads->ldap.wrap_type == ADS_SASLWRAP_TYPE_SEAL && conf_state == 0) { + return ADS_ERROR_NT(NT_STATUS_ACCESS_DENIED); + } + + if (wrapped.length < wrapped.length) { + return ADS_ERROR_NT(NT_STATUS_INTERNAL_ERROR); + } + + /* copy the wrapped blob to the right location */ + memcpy(ads->ldap.in.buf + 4, unwrapped.value, unwrapped.length); + + /* set how many bytes must be written to the underlying socket */ + ads->ldap.in.left = unwrapped.length; + ads->ldap.in.ofs = 4; + + gss_release_buffer(&minor_status, &unwrapped); + + return ADS_SUCCESS; +} + +static void ads_sasl_gssapi_disconnect(ADS_STRUCT *ads) +{ + gss_ctx_id_t context_handle = ads->ldap.wrap_private_data; + uint32 minor_status; + + gss_delete_sec_context(&minor_status, &context_handle, GSS_C_NO_BUFFER); + + ads->ldap.wrap_ops = NULL; + ads->ldap.wrap_private_data = NULL; +} + +static const struct ads_saslwrap_ops ads_sasl_gssapi_ops = { + .name = "gssapi", + .wrap = ads_sasl_gssapi_wrap, + .unwrap = ads_sasl_gssapi_unwrap, + .disconnect = ads_sasl_gssapi_disconnect +}; +#endif + #ifdef HAVE_KRB5 /* perform a LDAP/SASL/SPNEGO/KRB5 bind @@ -424,7 +523,8 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) gss_ctx_id_t context_handle = GSS_C_NO_CONTEXT; gss_OID mech_type = GSS_C_NULL_OID; gss_buffer_desc output_token, input_token; - uint32 ret_flags, conf_state; + uint32 req_flags, ret_flags; + int conf_state; struct berval cred; struct berval *scred = NULL; int i=0; @@ -491,13 +591,25 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) input_token.value = NULL; input_token.length = 0; + req_flags = GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG; + switch (ads->ldap.wrap_type) { + case ADS_SASLWRAP_TYPE_SEAL: + req_flags |= GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG; + break; + case ADS_SASLWRAP_TYPE_SIGN: + req_flags |= GSS_C_INTEG_FLAG; + break; + case ADS_SASLWRAP_TYPE_PLAIN: + break; + } + for (i=0; i < MAX_GSS_PASSES; i++) { gss_rc = gss_init_sec_context(&minor_status, GSS_C_NO_CREDENTIAL, &context_handle, serv_name, mech_type, - GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG, + req_flags, 0, NULL, &input_token, @@ -541,7 +653,7 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) } gss_rc = gss_unwrap(&minor_status,context_handle,&input_token,&output_token, - (int *)&conf_state,NULL); + &conf_state,NULL); if (gss_rc) { status = ADS_ERROR_GSS(gss_rc, minor_status); goto failed; @@ -565,7 +677,7 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) output_token.value = SMB_MALLOC(output_token.length); p = (uint8 *)output_token.value; - *p++ = 1; /* no sign & seal selection */ + *p++ = ads->ldap.wrap_type; /* choose the same size as the server gave us */ *p++ = max_msg_size>>16; *p++ = max_msg_size>>8; @@ -580,7 +692,7 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) */ gss_rc = gss_wrap(&minor_status, context_handle,0,GSS_C_QOP_DEFAULT, - &output_token, (int *)&conf_state, + &output_token, &conf_state, &input_token); if (gss_rc) { status = ADS_ERROR_GSS(gss_rc, minor_status); @@ -598,6 +710,24 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) gss_release_buffer(&minor_status, &input_token); + if (ads->ldap.wrap_type > ADS_SASLWRAP_TYPE_PLAIN) { + gss_rc = gss_wrap_size_limit(&minor_status, context_handle, + (ads->ldap.wrap_type == ADS_SASLWRAP_TYPE_SEAL), + GSS_C_QOP_DEFAULT, + max_msg_size, &ads->ldap.out.max); + if (gss_rc) { + status = ADS_ERROR_GSS(gss_rc, minor_status); + goto failed; + } + + ads->ldap.out.min = 4; + ads->ldap.out.sig_size = max_msg_size - ads->ldap.out.max; + ads->ldap.in.min = 4; + ads->ldap.in.max = max_msg_size; + ads_setup_sasl_wrapping(ads, &ads_sasl_gssapi_ops, context_handle); + /* make sure we don't free context_handle */ + context_handle = GSS_C_NO_CONTEXT; + } failed: gss_release_name(&minor_status, &serv_name); -- cgit From e6875b1b45577917ff9b465623502f49755aa612 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 18 Jul 2007 11:21:21 +0000 Subject: r23951: Fix segfault. Guenther (This used to be commit 1a5c8780ae79e5ae4e6a36bfb66cd92ae7d3aa88) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 0b73229736..6c9bde24b0 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -425,7 +425,7 @@ got_connection: return ADS_SUCCESS; } - ads->ldap.mem_ctx = talloc_new("ads LDAP connection memory"); + ads->ldap.mem_ctx = talloc_init("ads LDAP connection memory"); if (!ads->ldap.mem_ctx) { return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); } -- cgit From f5033a1e625f74c517751bdb13f12f625ad34eb4 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 18 Jul 2007 12:28:32 +0000 Subject: r23953: Some C++ warnings (This used to be commit 8716edf157bf8866328f82eb6cf25e71af7fea15) --- source3/libads/sasl.c | 9 ++++++--- source3/libads/sasl_wrapping.c | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index f423464a07..a3636ec2be 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -23,7 +23,8 @@ static ADS_STATUS ads_sasl_ntlmssp_wrap(ADS_STRUCT *ads, uint8 *buf, uint32 len) { - struct ntlmssp_state *ntlmssp_state = ads->ldap.wrap_private_data; + struct ntlmssp_state *ntlmssp_state = + (struct ntlmssp_state *)ads->ldap.wrap_private_data; ADS_STATUS status; NTSTATUS nt_status; DATA_BLOB sig; @@ -61,7 +62,8 @@ static ADS_STATUS ads_sasl_ntlmssp_wrap(ADS_STRUCT *ads, uint8 *buf, uint32 len) static ADS_STATUS ads_sasl_ntlmssp_unwrap(ADS_STRUCT *ads) { - struct ntlmssp_state *ntlmssp_state = ads->ldap.wrap_private_data; + struct ntlmssp_state *ntlmssp_state = + (struct ntlmssp_state *)ads->ldap.wrap_private_data; ADS_STATUS status; NTSTATUS nt_status; DATA_BLOB sig; @@ -95,7 +97,8 @@ static ADS_STATUS ads_sasl_ntlmssp_unwrap(ADS_STRUCT *ads) static void ads_sasl_ntlmssp_disconnect(ADS_STRUCT *ads) { - struct ntlmssp_state *ntlmssp_state = ads->ldap.wrap_private_data; + struct ntlmssp_state *ntlmssp_state = + (struct ntlmssp_state *)ads->ldap.wrap_private_data; ntlmssp_end(&ntlmssp_state); diff --git a/source3/libads/sasl_wrapping.c b/source3/libads/sasl_wrapping.c index 931273f40c..c620aae7ac 100644 --- a/source3/libads/sasl_wrapping.c +++ b/source3/libads/sasl_wrapping.c @@ -213,7 +213,7 @@ static ber_slen_t ads_saslwrap_write(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_ ret = ads_saslwrap_prepare_outbuf(ads, rlen); if (ret < 0) return ret; - status = ads->ldap.wrap_ops->wrap(ads, buf, rlen); + status = ads->ldap.wrap_ops->wrap(ads, (uint8 *)buf, rlen); if (!ADS_ERR_OK(status)) { errno = EACCES; return -1; -- cgit From fce64f683346192c86341b9dd0a0a8e0f83157dc Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 19 Jul 2007 13:34:45 +0000 Subject: r23969: Some helper routines to retrieve a PAC and PAC elements. Guenther (This used to be commit d4c87c792a955be7d5ef59fc683fc48e3d8afe16) --- source3/libads/authdata.c | 160 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c index d61ffc2397..4610bcb59d 100644 --- a/source3/libads/authdata.c +++ b/source3/libads/authdata.c @@ -955,4 +955,164 @@ out: return logon_info; } +/**************************************************************** +****************************************************************/ + + NTSTATUS kerberos_return_pac(TALLOC_CTX *mem_ctx, + const char *name, + const char *pass, + time_t time_offset, + PAC_DATA **pac_ret) +{ + krb5_error_code ret; + NTSTATUS status = NT_STATUS_INVALID_PARAMETER; + DATA_BLOB tkt, ap_rep, sesskey1, sesskey2; + PAC_DATA *pac_data = NULL; + char *client_princ_out = NULL; + const char *auth_princ = NULL; + const char *local_service = NULL; + const char *cc = "MEMORY:kerberos_return_pac"; + + ZERO_STRUCT(tkt); + ZERO_STRUCT(ap_rep); + ZERO_STRUCT(sesskey1); + ZERO_STRUCT(sesskey2); + + if (!name || !pass) { + return NT_STATUS_INVALID_PARAMETER; + } + + if (!strchr_m(name, '@')) { + auth_princ = talloc_asprintf(mem_ctx, "%s@%s", name, + lp_realm()); + } else { + auth_princ = name; + } + NT_STATUS_HAVE_NO_MEMORY(auth_princ); + + local_service = talloc_asprintf(mem_ctx, "%s$@%s", + global_myname(), lp_realm()); + NT_STATUS_HAVE_NO_MEMORY(local_service); + + ret = kerberos_kinit_password_ext(auth_princ, + pass, + time_offset, + NULL, + NULL, + cc, + True, + True, + 0, + &status); + if (ret) { + /* status already set */ + goto out; + } + + ret = cli_krb5_get_ticket(local_service, + time_offset, + &tkt, + &sesskey1, + 0, + cc, + NULL); + if (ret) { + status = krb5_to_nt_status(ret); + goto out; + } + + status = ads_verify_ticket(mem_ctx, + lp_realm(), + time_offset, + &tkt, + &client_princ_out, + &pac_data, + &ap_rep, + &sesskey2, + False); + if (!NT_STATUS_IS_OK(status)) { + goto out; + } + + if (!pac_data) { + status = NT_STATUS_INVALID_PARAMETER; + goto out; + } + + *pac_ret = pac_data; + +out: + ads_kdestroy(cc); + + data_blob_free(&tkt); + data_blob_free(&ap_rep); + data_blob_free(&sesskey1); + data_blob_free(&sesskey2); + + SAFE_FREE(client_princ_out); + + return status; +} + +/**************************************************************** +****************************************************************/ + +static NTSTATUS kerberos_return_pac_logon_info(TALLOC_CTX *mem_ctx, + const char *name, + const char *pass, + time_t time_offset, + PAC_LOGON_INFO **logon_info) +{ + NTSTATUS status; + PAC_DATA *pac_data = NULL; + PAC_LOGON_INFO *info = NULL; + + status = kerberos_return_pac(mem_ctx, + name, + pass, + time_offset, + &pac_data); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (!pac_data) { + return NT_STATUS_INVALID_USER_BUFFER; + } + + info = get_logon_info_from_pac(pac_data); + if (!info) { + return NT_STATUS_INVALID_USER_BUFFER; + } + + *logon_info = info; + + return NT_STATUS_OK; +} + +/**************************************************************** +****************************************************************/ + +NTSTATUS kerberos_return_info3_from_pac(TALLOC_CTX *mem_ctx, + const char *name, + const char *pass, + time_t time_offset, + NET_USER_INFO_3 **info3) +{ + NTSTATUS status; + PAC_LOGON_INFO *logon_info = NULL; + + status = kerberos_return_pac_logon_info(mem_ctx, + name, + pass, + time_offset, + &logon_info); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + *info3 = &logon_info->info3; + + return NT_STATUS_OK; +} #endif -- cgit From f659ffc0ee6acfb79edb00f4c985e940f8c5ddaa Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 19 Jul 2007 13:36:41 +0000 Subject: r23970: Allow to set the debuglevel at which to dump the PAC logon info. Guenther (This used to be commit 7d321aad83cb7b9cc766bc89a886676337a2bad8) --- source3/libads/authdata.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c index 4610bcb59d..5616ccd5a5 100644 --- a/source3/libads/authdata.c +++ b/source3/libads/authdata.c @@ -6,7 +6,7 @@ Copyright (C) Andrew Tridgell 2001 Copyright (C) Luke Howard 2002-2003 Copyright (C) Stefan Metzmacher 2004-2005 - Copyright (C) Guenther Deschner 2005 + Copyright (C) Guenther Deschner 2005,2007 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -723,8 +723,8 @@ char *pac_group_attr_string(uint32 attr) } /* just for debugging, will be removed later - Guenther */ -static void dump_pac_logon_info(PAC_LOGON_INFO *logon_info) { - +static void dump_pac_logon_info(int lvl, PAC_LOGON_INFO *logon_info) +{ DOM_SID dom_sid, res_group_dom_sid; int i; char *attr_string; @@ -734,21 +734,21 @@ static void dump_pac_logon_info(PAC_LOGON_INFO *logon_info) { sid_copy(&res_group_dom_sid, &logon_info->res_group_dom_sid.sid); } sid_copy(&dom_sid, &logon_info->info3.dom_sid.sid); - - DEBUG(10,("The PAC:\n")); - - DEBUGADD(10,("\tUser Flags: 0x%x (%d)\n", user_flgs, user_flgs)); + + DEBUG(lvl,("The PAC:\n")); + + DEBUGADD(lvl,("\tUser Flags: 0x%x (%d)\n", user_flgs, user_flgs)); if (user_flgs & LOGON_EXTRA_SIDS) - DEBUGADD(10,("\tUser Flags: LOGON_EXTRA_SIDS 0x%x (%d)\n", LOGON_EXTRA_SIDS, LOGON_EXTRA_SIDS)); + DEBUGADD(lvl,("\tUser Flags: LOGON_EXTRA_SIDS 0x%x (%d)\n", LOGON_EXTRA_SIDS, LOGON_EXTRA_SIDS)); if (user_flgs & LOGON_RESOURCE_GROUPS) - DEBUGADD(10,("\tUser Flags: LOGON_RESOURCE_GROUPS 0x%x (%d)\n", LOGON_RESOURCE_GROUPS, LOGON_RESOURCE_GROUPS)); - DEBUGADD(10,("\tUser SID: %s-%d\n", sid_string_static(&dom_sid), logon_info->info3.user_rid)); - DEBUGADD(10,("\tGroup SID: %s-%d\n", sid_string_static(&dom_sid), logon_info->info3.group_rid)); + DEBUGADD(lvl,("\tUser Flags: LOGON_RESOURCE_GROUPS 0x%x (%d)\n", LOGON_RESOURCE_GROUPS, LOGON_RESOURCE_GROUPS)); + DEBUGADD(lvl,("\tUser SID: %s-%d\n", sid_string_static(&dom_sid), logon_info->info3.user_rid)); + DEBUGADD(lvl,("\tGroup SID: %s-%d\n", sid_string_static(&dom_sid), logon_info->info3.group_rid)); - DEBUGADD(10,("\tGroup Membership (Global and Universal Groups of own domain):\n")); + DEBUGADD(lvl,("\tGroup Membership (Global and Universal Groups of own domain):\n")); for (i = 0; i < logon_info->info3.num_groups; i++) { attr_string = pac_group_attr_string(logon_info->info3.gids[i].attr); - DEBUGADD(10,("\t\t%d: sid: %s-%d\n\t\t attr: 0x%x == %s\n", + DEBUGADD(lvl,("\t\t%d: sid: %s-%d\n\t\t attr: 0x%x == %s\n", i, sid_string_static(&dom_sid), logon_info->info3.gids[i].g_rid, logon_info->info3.gids[i].attr, @@ -756,20 +756,20 @@ static void dump_pac_logon_info(PAC_LOGON_INFO *logon_info) { SAFE_FREE(attr_string); } - DEBUGADD(10,("\tGroup Membership (Domain Local Groups and Groups from Trusted Domains):\n")); + DEBUGADD(lvl,("\tGroup Membership (Domain Local Groups and Groups from Trusted Domains):\n")); for (i = 0; i < logon_info->info3.num_other_sids; i++) { attr_string = pac_group_attr_string(logon_info->info3.other_sids_attrib[i]); - DEBUGADD(10,("\t\t%d: sid: %s\n\t\t attr: 0x%x == %s\n", + DEBUGADD(lvl,("\t\t%d: sid: %s\n\t\t attr: 0x%x == %s\n", i, sid_string_static(&logon_info->info3.other_sids[i].sid), logon_info->info3.other_sids_attrib[i], attr_string)); SAFE_FREE(attr_string); } - DEBUGADD(10,("\tGroup Membership (Ressource Groups (SID History ?)):\n")); + DEBUGADD(lvl,("\tGroup Membership (Ressource Groups (SID History ?)):\n")); for (i = 0; i < logon_info->info3.res_group_count; i++) { attr_string = pac_group_attr_string(logon_info->res_groups.group_membership[i].attrs); - DEBUGADD(10,("\t\t%d: sid: %s-%d\n\t\t attr: 0x%x == %s\n", + DEBUGADD(lvl,("\t\t%d: sid: %s-%d\n\t\t attr: 0x%x == %s\n", i, sid_string_static(&res_group_dom_sid), logon_info->res_groups.group_membership[i].rid, logon_info->res_groups.group_membership[i].attrs, @@ -925,7 +925,7 @@ static void dump_pac_logon_info(PAC_LOGON_INFO *logon_info) { DEBUG(10,("Successfully validated Kerberos PAC\n")); - dump_pac_logon_info(logon_info); + dump_pac_logon_info(10, logon_info); *pac_data = my_pac; -- cgit From 2349acdd4366f665b9091d879682bc578b03c42d Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 19 Jul 2007 13:47:53 +0000 Subject: r23973: For debugging, add (undocumented) net ads kerberos commands (kinit, renew, pac). Guenther (This used to be commit 4cada7c1485c9957e553d6e75cb6f30f4338489f) --- source3/libads/authdata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c index 5616ccd5a5..b19bec43c5 100644 --- a/source3/libads/authdata.c +++ b/source3/libads/authdata.c @@ -723,7 +723,7 @@ char *pac_group_attr_string(uint32 attr) } /* just for debugging, will be removed later - Guenther */ -static void dump_pac_logon_info(int lvl, PAC_LOGON_INFO *logon_info) +void dump_pac_logon_info(int lvl, PAC_LOGON_INFO *logon_info) { DOM_SID dom_sid, res_group_dom_sid; int i; -- cgit From 6b5c55b0f0155a2615683faccee9427c0aaf4baa Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 25 Jul 2007 07:23:20 +0000 Subject: r24037: only setup sasl wrapping after a successful bind metze (This used to be commit 85d6cd3dfb5cbd9e899957265e352583ff608ed4) --- source3/libads/sasl.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index a3636ec2be..d1cd9f4f0b 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -709,9 +709,11 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) rc = ldap_sasl_bind_s(ads->ldap.ld, NULL, "GSSAPI", &cred, NULL, NULL, &scred); - status = ADS_ERROR(rc); - gss_release_buffer(&minor_status, &input_token); + status = ADS_ERROR(rc); + if (!ADS_ERR_OK(status)) { + goto failed; + } if (ads->ldap.wrap_type > ADS_SASLWRAP_TYPE_PLAIN) { gss_rc = gss_wrap_size_limit(&minor_status, context_handle, -- cgit From 75ae998b9948c03956ead9c3f9c7344a96ab93dc Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 25 Jul 2007 10:34:16 +0000 Subject: r24042: add support for krb5 sign and seal in LDAP via "GSS-SPNEGO" metze (This used to be commit 34ab84aceb86195743abd26c46a631640409725e) --- source3/libads/sasl.c | 310 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 309 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index d1cd9f4f0b..6c5a518e6a 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -356,19 +356,307 @@ static const struct ads_saslwrap_ops ads_sasl_gssapi_ops = { .unwrap = ads_sasl_gssapi_unwrap, .disconnect = ads_sasl_gssapi_disconnect }; + +/* + perform a LDAP/SASL/SPNEGO/GSSKRB5 bind +*/ +static ADS_STATUS ads_sasl_spnego_gsskrb5_bind(ADS_STRUCT *ads, const char *sname) +{ + ADS_STATUS status; + BOOL ok; + uint32 minor_status; + int gss_rc, rc; + gss_OID_desc krb5_mech_type = + {9, CONST_DISCARD(char *, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02") }; + gss_OID mech_type = &krb5_mech_type; + gss_OID actual_mech_type = GSS_C_NULL_OID; + const char *spnego_mechs[] = {OID_KERBEROS5_OLD, OID_KERBEROS5, OID_NTLMSSP, NULL}; + gss_name_t serv_name; + gss_ctx_id_t context_handle = GSS_C_NO_CONTEXT; + gss_buffer_desc input_token, output_token; + uint32 req_flags, ret_flags; + uint32 req_tmp, ret_tmp; + DATA_BLOB unwrapped; + DATA_BLOB wrapped; + struct berval cred, *scred = NULL; + krb5_principal principal = NULL; + gss_buffer_desc input_name; + krb5_context ctx = NULL; + krb5_enctype enc_types[] = { +#ifdef ENCTYPE_ARCFOUR_HMAC + ENCTYPE_ARCFOUR_HMAC, +#endif + ENCTYPE_DES_CBC_MD5, + ENCTYPE_NULL}; + gss_OID_desc nt_principal = + {10, CONST_DISCARD(char *, "\052\206\110\206\367\022\001\002\002\002")}; + + initialize_krb5_error_table(); + status = ADS_ERROR_KRB5(krb5_init_context(&ctx)); + if (!ADS_ERR_OK(status)) { + return status; + } + status = ADS_ERROR_KRB5(krb5_set_default_tgs_ktypes(ctx, enc_types)); + if (!ADS_ERR_OK(status)) { + krb5_free_context(ctx); + return status; + } + status = ADS_ERROR_KRB5(smb_krb5_parse_name(ctx, sname, &principal)); + if (!ADS_ERR_OK(status)) { + krb5_free_context(ctx); + return status; + } + + /* + * The MIT libraries have a *HORRIBLE* bug - input_value.value needs + * to point to the *address* of the krb5_principal, and the gss libraries + * to a shallow copy of the krb5_principal pointer - so we need to keep + * the krb5_principal around until we do the gss_release_name. MIT *SUCKS* ! + * Just one more way in which MIT engineers screwed me over.... JRA. + */ + input_name.value = &principal; + input_name.length = sizeof(principal); + + gss_rc = gss_import_name(&minor_status, &input_name, &nt_principal, &serv_name); + if (gss_rc) { + krb5_free_principal(ctx, principal); + krb5_free_context(ctx); + return ADS_ERROR_GSS(gss_rc, minor_status); + } + + input_token.value = NULL; + input_token.length = 0; + + req_flags = GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG; + switch (ads->ldap.wrap_type) { + case ADS_SASLWRAP_TYPE_SEAL: + req_flags |= GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG; + break; + case ADS_SASLWRAP_TYPE_SIGN: + req_flags |= GSS_C_INTEG_FLAG; + break; + case ADS_SASLWRAP_TYPE_PLAIN: + break; + } + + /* Note: here we explicit ask for the krb5 mech_type */ + gss_rc = gss_init_sec_context(&minor_status, + GSS_C_NO_CREDENTIAL, + &context_handle, + serv_name, + mech_type, + req_flags, + 0, + NULL, + &input_token, + &actual_mech_type, + &output_token, + &ret_flags, + NULL); + if (gss_rc && gss_rc != GSS_S_CONTINUE_NEEDED) { + status = ADS_ERROR_GSS(gss_rc, minor_status); + goto failed; + } + + /* + * As some gssapi krb5 mech implementations + * automaticly add GSS_C_INTEG_FLAG and GSS_C_CONF_FLAG + * to req_flags internaly, it's not possible to + * use plain or signing only connection via + * the gssapi interface. + * + * Because of this we need to check it the ret_flags + * has more flags as req_flags and correct the value + * of ads->ldap.wrap_type. + * + * I ads->auth.flags has ADS_AUTH_SASL_FORCE + * we need to give an error. + */ + req_tmp = req_flags & (GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG); + ret_tmp = ret_flags & (GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG); + + if (req_tmp == ret_tmp) { + /* everythings fine... */ + + } else if (req_flags & GSS_C_CONF_FLAG) { + /* + * here we wanted sealing but didn't got it + * from the gssapi library + */ + status = ADS_ERROR_NT(NT_STATUS_NOT_SUPPORTED); + goto failed; + + } else if (req_flags & GSS_C_INTEG_FLAG) { + /* + * here we wanted siging but didn't got it + * from the gssapi library + */ + status = ADS_ERROR_NT(NT_STATUS_NOT_SUPPORTED); + goto failed; + + } else if (ret_flags & GSS_C_CONF_FLAG) { + /* + * here we didn't want sealing + * but the gssapi library forces it + * so correct the needed wrap_type if + * the caller didn't forced siging only + */ + if (ads->auth.flags & ADS_AUTH_SASL_FORCE) { + status = ADS_ERROR_NT(NT_STATUS_NOT_SUPPORTED); + goto failed; + } + + ads->ldap.wrap_type = ADS_SASLWRAP_TYPE_SEAL; + req_flags = ret_flags; + + } else if (ret_flags & GSS_C_INTEG_FLAG) { + /* + * here we didn't want signing + * but the gssapi library forces it + * so correct the needed wrap_type if + * the caller didn't forced plain + */ + if (ads->auth.flags & ADS_AUTH_SASL_FORCE) { + status = ADS_ERROR_NT(NT_STATUS_NOT_SUPPORTED); + goto failed; + } + + ads->ldap.wrap_type = ADS_SASLWRAP_TYPE_SIGN; + req_flags = ret_flags; + } else { + /* + * This could (should?) not happen + */ + status = ADS_ERROR_NT(NT_STATUS_INTERNAL_ERROR); + goto failed; + + } + + /* and wrap that in a shiny SPNEGO wrapper */ + unwrapped = data_blob_const(output_token.value, output_token.length); + wrapped = gen_negTokenTarg(spnego_mechs, unwrapped); + gss_release_buffer(&minor_status, &output_token); + if (unwrapped.length > wrapped.length) { + status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + goto failed; + } + + cred.bv_val = (char *)wrapped.data; + cred.bv_len = wrapped.length; + + rc = ldap_sasl_bind_s(ads->ldap.ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, + &scred); + data_blob_free(&wrapped); + if (rc != LDAP_SUCCESS) { + status = ADS_ERROR(rc); + goto failed; + } + + if (scred) { + wrapped = data_blob_const(scred->bv_val, scred->bv_len); + } else { + wrapped = data_blob_null; + } + + ok = spnego_parse_auth_response(wrapped, NT_STATUS_OK, + OID_KERBEROS5_OLD, + &unwrapped); + if (scred) ber_bvfree(scred); + if (!ok) { + status = ADS_ERROR_NT(NT_STATUS_INVALID_NETWORK_RESPONSE); + goto failed; + } + + input_token.value = unwrapped.data; + input_token.length = unwrapped.length; + + /* + * As we asked for mutal authentication + * we need to pass the servers response + * to gssapi + */ + gss_rc = gss_init_sec_context(&minor_status, + GSS_C_NO_CREDENTIAL, + &context_handle, + serv_name, + mech_type, + req_flags, + 0, + NULL, + &input_token, + &actual_mech_type, + &output_token, + &ret_flags, + NULL); + data_blob_free(&unwrapped); + if (gss_rc) { + status = ADS_ERROR_GSS(gss_rc, minor_status); + goto failed; + } + + gss_release_buffer(&minor_status, &output_token); + + /* + * If we the sign and seal options + * doesn't match after getting the response + * from the server, we don't want to use the connection + */ + req_tmp = req_flags & (GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG); + ret_tmp = ret_flags & (GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG); + + if (req_tmp != ret_tmp) { + /* everythings fine... */ + status = ADS_ERROR_NT(NT_STATUS_INVALID_NETWORK_RESPONSE); + goto failed; + } + + if (ads->ldap.wrap_type > ADS_SASLWRAP_TYPE_PLAIN) { + uint32 max_msg_size = 0x0A000000; + + gss_rc = gss_wrap_size_limit(&minor_status, context_handle, + (ads->ldap.wrap_type == ADS_SASLWRAP_TYPE_SEAL), + GSS_C_QOP_DEFAULT, + max_msg_size, &ads->ldap.out.max); + if (gss_rc) { + status = ADS_ERROR_GSS(gss_rc, minor_status); + goto failed; + } + + ads->ldap.out.min = 4; + ads->ldap.out.sig_size = max_msg_size - ads->ldap.out.max; + ads->ldap.in.min = 4; + ads->ldap.in.max = max_msg_size; + ads_setup_sasl_wrapping(ads, &ads_sasl_gssapi_ops, context_handle); + /* make sure we don't free context_handle */ + context_handle = GSS_C_NO_CONTEXT; + } + +failed: + gss_release_name(&minor_status, &serv_name); + if (context_handle != GSS_C_NO_CONTEXT) + gss_delete_sec_context(&minor_status, &context_handle, GSS_C_NO_BUFFER); + krb5_free_principal(ctx, principal); + krb5_free_context(ctx); + return status; +} + #endif #ifdef HAVE_KRB5 /* perform a LDAP/SASL/SPNEGO/KRB5 bind */ -static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *principal) +static ADS_STATUS ads_sasl_spnego_rawkrb5_bind(ADS_STRUCT *ads, const char *principal) { DATA_BLOB blob = data_blob_null; struct berval cred, *scred = NULL; DATA_BLOB session_key = data_blob_null; int rc; + if (ads->ldap.wrap_type > ADS_SASLWRAP_TYPE_PLAIN) { + return ADS_ERROR_NT(NT_STATUS_NOT_SUPPORTED); + } + rc = spnego_gen_negTokenTarg(principal, ads->auth.time_offset, &blob, &session_key, 0, &ads->auth.tgs_expire); @@ -389,6 +677,26 @@ static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *princip return ADS_ERROR(rc); } + +static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *principal) +{ +#ifdef HAVE_GSSAPI + /* + * we only use the gsskrb5 based implementation + * when sasl sign or seal is requested. + * + * This has the following reasons: + * - it's likely that the gssapi krb5 mech implementation + * doesn't support to negotiate plain connections + * - the ads_sasl_spnego_rawkrb5_bind is more robust + * against clock skew errors + */ + if (ads->ldap.wrap_type > ADS_SASLWRAP_TYPE_PLAIN) { + return ads_sasl_spnego_gsskrb5_bind(ads, principal); + } +#endif + return ads_sasl_spnego_rawkrb5_bind(ads, principal); +} #endif /* -- cgit From d44063715accb8129a4c047c965fba9732d7c044 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 26 Jul 2007 17:27:03 +0000 Subject: r24058: Fix some memory leaks in ads_secrets_verify_ticket. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Jeremy, Günther, please review! Thanks, Volker (This used to be commit 000e096c277a71ca30c1c109aae62241ad466bee) --- source3/libads/kerberos_verify.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 378258ee08..ed889d027a 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -274,6 +274,7 @@ static krb5_error_code ads_secrets_verify_ticket(krb5_context context, auth_ok = True; krb5_copy_keyblock(context, key, keyblock); krb5_free_keyblock(context, key); + SAFE_FREE(key); break; } @@ -285,10 +286,12 @@ static krb5_error_code ads_secrets_verify_ticket(krb5_context context, if (ret == KRB5KRB_AP_ERR_TKT_NYV || ret == KRB5KRB_AP_ERR_TKT_EXPIRED || ret == KRB5KRB_AP_ERR_SKEW) { + SAFE_FREE(key); break; } krb5_free_keyblock(context, key); + SAFE_FREE(key); } -- cgit From b4f6db40ab24742f4d9a8b1ff4885e62092b5930 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 27 Jul 2007 07:19:36 +0000 Subject: r24062: fix logic for broken krb5 libs which always force sign and seal... metze (This used to be commit 4a4fc8cccbcbe17eebcefcd0107f7de60d751f5c) --- source3/libads/sasl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 6c5a518e6a..f5e540d304 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -486,7 +486,8 @@ static ADS_STATUS ads_sasl_spnego_gsskrb5_bind(ADS_STRUCT *ads, const char *snam status = ADS_ERROR_NT(NT_STATUS_NOT_SUPPORTED); goto failed; - } else if (req_flags & GSS_C_INTEG_FLAG) { + } else if ((req_flags & GSS_C_INTEG_FLAG) && + !(ret_flags & GSS_C_INTEG_FLAG)) { /* * here we wanted siging but didn't got it * from the gssapi library -- cgit From bf27a77c05031aab0d558583fc2e1dfbe50b327d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 27 Jul 2007 09:15:13 +0000 Subject: r24065: According to gd, this breaks heimdal. Thanks for checking! (This used to be commit ea5f53eac81e8a969587eb3996b16a1afd948877) --- source3/libads/kerberos_verify.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index ed889d027a..378258ee08 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -274,7 +274,6 @@ static krb5_error_code ads_secrets_verify_ticket(krb5_context context, auth_ok = True; krb5_copy_keyblock(context, key, keyblock); krb5_free_keyblock(context, key); - SAFE_FREE(key); break; } @@ -286,12 +285,10 @@ static krb5_error_code ads_secrets_verify_ticket(krb5_context context, if (ret == KRB5KRB_AP_ERR_TKT_NYV || ret == KRB5KRB_AP_ERR_TKT_EXPIRED || ret == KRB5KRB_AP_ERR_SKEW) { - SAFE_FREE(key); break; } krb5_free_keyblock(context, key); - SAFE_FREE(key); } -- cgit From 3ec8b1702cbda9d4f9dd276e2acef4057ee80a13 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 27 Jul 2007 09:22:43 +0000 Subject: r24066: Fix memleak found by Volker. We don't leak keys now with MIT and Heimdal. Guenther (This used to be commit 7755ad750facc44b6a5df2136cb536547048cd48) --- source3/libads/kerberos_verify.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 378258ee08..99288b78e5 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -285,6 +285,7 @@ static krb5_error_code ads_secrets_verify_ticket(krb5_context context, if (ret == KRB5KRB_AP_ERR_TKT_NYV || ret == KRB5KRB_AP_ERR_TKT_EXPIRED || ret == KRB5KRB_AP_ERR_SKEW) { + krb5_free_keyblock(context, key); break; } -- cgit From 31dc9126c1f401ac8668b3c46e28c5a47d34a090 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 30 Jul 2007 08:22:45 +0000 Subject: r24072: Add "client ldap sasl wrapping" parameter. Possible values are "plain" (default), "sign" or "seal". metze (This used to be commit 26ccbad7212e9acd480b98789f04b71c1e940ea8) --- source3/libads/ads_struct.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index c769d8ff48..aac57d41fe 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -109,6 +109,7 @@ ADS_STRUCT *ads_init(const char *realm, const char *ldap_server) { ADS_STRUCT *ads; + int wrap_flags; ads = SMB_XMALLOC_P(ADS_STRUCT); ZERO_STRUCTP(ads); @@ -128,6 +129,13 @@ ADS_STRUCT *ads_init(const char *realm, /* the caller will own the memory by default */ ads->is_mine = 1; + wrap_flags = lp_client_ldap_sasl_wrapping(); + if (wrap_flags == -1) { + wrap_flags = 0; + } + + ads->auth.flags = wrap_flags; + return ads; } -- cgit From 062bca6675c120dcf533de18da72acc903b3eb8e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 31 Jul 2007 09:31:47 +0000 Subject: r24093: move gssapi/krb5 principal handling into a function metze (This used to be commit 83de27968d434d67d23851b0c285221c870ff75e) --- source3/libads/sasl.c | 234 +++++++++++++++++++++++++++++++------------------- 1 file changed, 146 insertions(+), 88 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index f5e540d304..732691942f 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -360,7 +360,7 @@ static const struct ads_saslwrap_ops ads_sasl_gssapi_ops = { /* perform a LDAP/SASL/SPNEGO/GSSKRB5 bind */ -static ADS_STATUS ads_sasl_spnego_gsskrb5_bind(ADS_STRUCT *ads, const char *sname) +static ADS_STATUS ads_sasl_spnego_gsskrb5_bind(ADS_STRUCT *ads, const gss_name_t serv_name) { ADS_STATUS status; BOOL ok; @@ -371,7 +371,6 @@ static ADS_STATUS ads_sasl_spnego_gsskrb5_bind(ADS_STRUCT *ads, const char *snam gss_OID mech_type = &krb5_mech_type; gss_OID actual_mech_type = GSS_C_NULL_OID; const char *spnego_mechs[] = {OID_KERBEROS5_OLD, OID_KERBEROS5, OID_NTLMSSP, NULL}; - gss_name_t serv_name; gss_ctx_id_t context_handle = GSS_C_NO_CONTEXT; gss_buffer_desc input_token, output_token; uint32 req_flags, ret_flags; @@ -379,50 +378,6 @@ static ADS_STATUS ads_sasl_spnego_gsskrb5_bind(ADS_STRUCT *ads, const char *snam DATA_BLOB unwrapped; DATA_BLOB wrapped; struct berval cred, *scred = NULL; - krb5_principal principal = NULL; - gss_buffer_desc input_name; - krb5_context ctx = NULL; - krb5_enctype enc_types[] = { -#ifdef ENCTYPE_ARCFOUR_HMAC - ENCTYPE_ARCFOUR_HMAC, -#endif - ENCTYPE_DES_CBC_MD5, - ENCTYPE_NULL}; - gss_OID_desc nt_principal = - {10, CONST_DISCARD(char *, "\052\206\110\206\367\022\001\002\002\002")}; - - initialize_krb5_error_table(); - status = ADS_ERROR_KRB5(krb5_init_context(&ctx)); - if (!ADS_ERR_OK(status)) { - return status; - } - status = ADS_ERROR_KRB5(krb5_set_default_tgs_ktypes(ctx, enc_types)); - if (!ADS_ERR_OK(status)) { - krb5_free_context(ctx); - return status; - } - status = ADS_ERROR_KRB5(smb_krb5_parse_name(ctx, sname, &principal)); - if (!ADS_ERR_OK(status)) { - krb5_free_context(ctx); - return status; - } - - /* - * The MIT libraries have a *HORRIBLE* bug - input_value.value needs - * to point to the *address* of the krb5_principal, and the gss libraries - * to a shallow copy of the krb5_principal pointer - so we need to keep - * the krb5_principal around until we do the gss_release_name. MIT *SUCKS* ! - * Just one more way in which MIT engineers screwed me over.... JRA. - */ - input_name.value = &principal; - input_name.length = sizeof(principal); - - gss_rc = gss_import_name(&minor_status, &input_name, &nt_principal, &serv_name); - if (gss_rc) { - krb5_free_principal(ctx, principal); - krb5_free_context(ctx); - return ADS_ERROR_GSS(gss_rc, minor_status); - } input_token.value = NULL; input_token.length = 0; @@ -633,17 +588,136 @@ static ADS_STATUS ads_sasl_spnego_gsskrb5_bind(ADS_STRUCT *ads, const char *snam } failed: - gss_release_name(&minor_status, &serv_name); if (context_handle != GSS_C_NO_CONTEXT) gss_delete_sec_context(&minor_status, &context_handle, GSS_C_NO_BUFFER); - krb5_free_principal(ctx, principal); - krb5_free_context(ctx); return status; } #endif #ifdef HAVE_KRB5 +struct ads_service_principal { + krb5_context ctx; + char *string; + krb5_principal principal; +#ifdef HAVE_GSSAPI + gss_name_t name; +#endif +}; + +static void ads_free_service_principal(struct ads_service_principal *p) +{ + SAFE_FREE(p->string); + +#ifdef HAVE_GSSAPI + if (p->name) { + uint32 minor_status; + gss_release_name(&minor_status, &p->name); + } +#endif + if (p->principal) { + krb5_free_principal(p->ctx, p->principal); + } + + if (p->ctx) { + krb5_free_context(p->ctx); + } + + ZERO_STRUCTP(p); +} + +static ADS_STATUS ads_generate_service_principal(ADS_STRUCT *ads, + const char *given_principal, + struct ads_service_principal *p) +{ + ADS_STATUS status; + krb5_enctype enc_types[] = { +#ifdef ENCTYPE_ARCFOUR_HMAC + ENCTYPE_ARCFOUR_HMAC, +#endif + ENCTYPE_DES_CBC_MD5, + ENCTYPE_NULL}; +#ifdef HAVE_GSSAPI + gss_buffer_desc input_name; + gss_OID_desc nt_principal = + {10, CONST_DISCARD(char *, "\052\206\110\206\367\022\001\002\002\002")}; + uint32 minor_status; + int gss_rc; +#endif + + ZERO_STRUCTP(p); + + /* I've seen a child Windows 2000 domain not send + the principal name back in the first round of + the SASL bind reply. So we guess based on server + name and realm. --jerry */ + if (given_principal) { + p->string = SMB_STRDUP(given_principal); + if (!p->string) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + } else if (ads->server.realm && ads->server.ldap_server) { + char *server, *server_realm; + + server = SMB_STRDUP(ads->server.ldap_server); + server_realm = SMB_STRDUP(ads->server.realm); + + if (!server || !server_realm) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + + strlower_m(server); + strupper_m(server_realm); + asprintf(&p->string, "ldap/%s@%s", server, server_realm); + + SAFE_FREE(server); + SAFE_FREE(server_realm); + + if (!p->string) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + } + + initialize_krb5_error_table(); + status = ADS_ERROR_KRB5(krb5_init_context(&p->ctx)); + if (!ADS_ERR_OK(status)) { + ads_free_service_principal(p); + return status; + } + status = ADS_ERROR_KRB5(krb5_set_default_tgs_ktypes(p->ctx, enc_types)); + if (!ADS_ERR_OK(status)) { + ads_free_service_principal(p); + return status; + } + status = ADS_ERROR_KRB5(smb_krb5_parse_name(p->ctx, p->string, &p->principal)); + if (!ADS_ERR_OK(status)) { + ads_free_service_principal(p); + return status; + } + +#ifdef HAVE_GSSAPI + /* + * The MIT libraries have a *HORRIBLE* bug - input_value.value needs + * to point to the *address* of the krb5_principal, and the gss libraries + * to a shallow copy of the krb5_principal pointer - so we need to keep + * the krb5_principal around until we do the gss_release_name. MIT *SUCKS* ! + * Just one more way in which MIT engineers screwed me over.... JRA. + * + * That's the reason for principal not beeing a local var in this function + */ + input_name.value = &p->principal; + input_name.length = sizeof(p->principal); + + gss_rc = gss_import_name(&minor_status, &input_name, &nt_principal, &p->name); + if (gss_rc) { + ads_free_service_principal(p); + return ADS_ERROR_GSS(gss_rc, minor_status); + } +#endif + + return status; +} + /* perform a LDAP/SASL/SPNEGO/KRB5 bind */ @@ -679,7 +753,8 @@ static ADS_STATUS ads_sasl_spnego_rawkrb5_bind(ADS_STRUCT *ads, const char *prin return ADS_ERROR(rc); } -static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *principal) +static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, + struct ads_service_principal *p) { #ifdef HAVE_GSSAPI /* @@ -693,10 +768,10 @@ static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *princip * against clock skew errors */ if (ads->ldap.wrap_type > ADS_SASLWRAP_TYPE_PLAIN) { - return ads_sasl_spnego_gsskrb5_bind(ads, principal); + return ads_sasl_spnego_gsskrb5_bind(ads, p->name); } #endif - return ads_sasl_spnego_rawkrb5_bind(ads, principal); + return ads_sasl_spnego_rawkrb5_bind(ads, p->string); } #endif @@ -709,7 +784,7 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) int rc, i; ADS_STATUS status; DATA_BLOB blob; - char *principal = NULL; + char *given_principal = NULL; char *OIDs[ASN1_MAX_OIDS]; #ifdef HAVE_KRB5 BOOL got_kerberos_mechanism = False; @@ -732,7 +807,7 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) /* the server sent us the first part of the SPNEGO exchange in the negprot reply */ - if (!spnego_parse_negTokenInit(blob, OIDs, &principal)) { + if (!spnego_parse_negTokenInit(blob, OIDs, &given_principal)) { data_blob_free(&blob); status = ADS_ERROR(LDAP_OPERATIONS_ERROR); goto failed; @@ -750,42 +825,23 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) #endif free(OIDs[i]); } - DEBUG(3,("ads_sasl_spnego_bind: got server principal name = %s\n", principal)); + DEBUG(3,("ads_sasl_spnego_bind: got server principal name = %s\n", given_principal)); #ifdef HAVE_KRB5 if (!(ads->auth.flags & ADS_AUTH_DISABLE_KERBEROS) && got_kerberos_mechanism) { - /* I've seen a child Windows 2000 domain not send - the principal name back in the first round of - the SASL bind reply. So we guess based on server - name and realm. --jerry */ - if ( !principal ) { - if ( ads->server.realm && ads->server.ldap_server ) { - char *server, *server_realm; - - server = SMB_STRDUP( ads->server.ldap_server ); - server_realm = SMB_STRDUP( ads->server.realm ); - - if ( !server || !server_realm ) - return ADS_ERROR(LDAP_NO_MEMORY); - - strlower_m( server ); - strupper_m( server_realm ); - asprintf( &principal, "ldap/%s@%s", server, server_realm ); - - SAFE_FREE( server ); - SAFE_FREE( server_realm ); - - if ( !principal ) - return ADS_ERROR(LDAP_NO_MEMORY); - } - + struct ads_service_principal p; + + status = ads_generate_service_principal(ads, given_principal, &p); + SAFE_FREE(given_principal); + if (!ADS_ERR_OK(status)) { + return status; } - - status = ads_sasl_spnego_krb5_bind(ads, principal); + + status = ads_sasl_spnego_krb5_bind(ads, &p); if (ADS_ERR_OK(status)) { - SAFE_FREE(principal); + ads_free_service_principal(&p); return status; } @@ -795,19 +851,21 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) status = ADS_ERROR_KRB5(ads_kinit_password(ads)); if (ADS_ERR_OK(status)) { - status = ads_sasl_spnego_krb5_bind(ads, principal); + status = ads_sasl_spnego_krb5_bind(ads, &p); } + ads_free_service_principal(&p); + /* only fallback to NTLMSSP if allowed */ if (ADS_ERR_OK(status) || !(ads->auth.flags & ADS_AUTH_ALLOW_NTLMSSP)) { - SAFE_FREE(principal); return status; } - } + } else #endif - - SAFE_FREE(principal); + { + SAFE_FREE(given_principal); + } /* lets do NTLMSSP ... this has the big advantage that we don't need to sync clocks, and we don't rely on special versions of the krb5 -- cgit From db718085fd7a614215f1994f9001e9c04a37426b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 31 Jul 2007 09:37:25 +0000 Subject: r24095: add one more fallback alternative to construct the principal metze (This used to be commit b545667d2a45a79bba05c9fe9e93a19951d60af7) --- source3/libads/sasl.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 732691942f..4436551d88 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -673,6 +673,26 @@ static ADS_STATUS ads_generate_service_principal(ADS_STRUCT *ads, SAFE_FREE(server); SAFE_FREE(server_realm); + if (!p->string) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + } else if (ads->config.realm && ads->config.ldap_server_name) { + char *server, *server_realm; + + server = SMB_STRDUP(ads->config.ldap_server_name); + server_realm = SMB_STRDUP(ads->config.realm); + + if (!server || !server_realm) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + + strlower_m(server); + strupper_m(server_realm); + asprintf(&p->string, "ldap/%s@%s", server, server_realm); + + SAFE_FREE(server); + SAFE_FREE(server_realm); + if (!p->string) { return ADS_ERROR(LDAP_NO_MEMORY); } -- cgit From 3edc6088aaff282530435ca19f70a96b22f045f4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 31 Jul 2007 09:49:14 +0000 Subject: r24098: - make use of the ads_service_principal abstraction also for the "GSSAPI" sasl mech. - also use the ads_kinit_password() fallback logic from the "GSS-SPNEGO" sasl mech. metze (This used to be commit cbaf44de1e1f8007dc4ca249791ea30d2902c7c4) --- source3/libads/sasl.c | 93 ++++++++++++++++++--------------------------------- 1 file changed, 32 insertions(+), 61 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 4436551d88..0bc741c02a 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -905,11 +905,9 @@ failed: this routine is much less fragile see RFC2078 and RFC2222 for details */ -static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) +static ADS_STATUS ads_sasl_gssapi_do_bind(ADS_STRUCT *ads, const gss_name_t serv_name) { uint32 minor_status; - gss_name_t serv_name; - gss_buffer_desc input_name; gss_ctx_id_t context_handle = GSS_C_NO_CONTEXT; gss_OID mech_type = GSS_C_NULL_OID; gss_buffer_desc output_token, input_token; @@ -921,62 +919,7 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) int gss_rc, rc; uint8 *p; uint32 max_msg_size = 0; - char *sname = NULL; ADS_STATUS status; - krb5_principal principal = NULL; - krb5_context ctx = NULL; - krb5_enctype enc_types[] = { -#ifdef ENCTYPE_ARCFOUR_HMAC - ENCTYPE_ARCFOUR_HMAC, -#endif - ENCTYPE_DES_CBC_MD5, - ENCTYPE_NULL}; - gss_OID_desc nt_principal = - {10, CONST_DISCARD(char *, "\052\206\110\206\367\022\001\002\002\002")}; - - /* we need to fetch a service ticket as the ldap user in the - servers realm, regardless of our realm */ - asprintf(&sname, "ldap/%s@%s", ads->config.ldap_server_name, ads->config.realm); - - initialize_krb5_error_table(); - status = ADS_ERROR_KRB5(krb5_init_context(&ctx)); - if (!ADS_ERR_OK(status)) { - SAFE_FREE(sname); - return status; - } - status = ADS_ERROR_KRB5(krb5_set_default_tgs_ktypes(ctx, enc_types)); - if (!ADS_ERR_OK(status)) { - SAFE_FREE(sname); - krb5_free_context(ctx); - return status; - } - status = ADS_ERROR_KRB5(smb_krb5_parse_name(ctx, sname, &principal)); - if (!ADS_ERR_OK(status)) { - SAFE_FREE(sname); - krb5_free_context(ctx); - return status; - } - - input_name.value = &principal; - input_name.length = sizeof(principal); - - gss_rc = gss_import_name(&minor_status, &input_name, &nt_principal, &serv_name); - - /* - * The MIT libraries have a *HORRIBLE* bug - input_value.value needs - * to point to the *address* of the krb5_principal, and the gss libraries - * to a shallow copy of the krb5_principal pointer - so we need to keep - * the krb5_principal around until we do the gss_release_name. MIT *SUCKS* ! - * Just one more way in which MIT engineers screwed me over.... JRA. - */ - - SAFE_FREE(sname); - - if (gss_rc) { - krb5_free_principal(ctx, principal); - krb5_free_context(ctx); - return ADS_ERROR_GSS(gss_rc, minor_status); - } input_token.value = NULL; input_token.length = 0; @@ -1122,16 +1065,44 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) } failed: - gss_release_name(&minor_status, &serv_name); if (context_handle != GSS_C_NO_CONTEXT) gss_delete_sec_context(&minor_status, &context_handle, GSS_C_NO_BUFFER); - krb5_free_principal(ctx, principal); - krb5_free_context(ctx); if(scred) ber_bvfree(scred); return status; } + +static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) +{ + ADS_STATUS status; + struct ads_service_principal p; + + status = ads_generate_service_principal(ads, NULL, &p); + if (!ADS_ERR_OK(status)) { + return status; + } + + status = ads_sasl_gssapi_do_bind(ads, p.name); + if (ADS_ERR_OK(status)) { + ads_free_service_principal(&p); + return status; + } + + DEBUG(10,("ads_sasl_gssapi_do_bind failed with: %s, " + "calling kinit\n", ads_errstr(status))); + + status = ADS_ERROR_KRB5(ads_kinit_password(ads)); + + if (ADS_ERR_OK(status)) { + status = ads_sasl_gssapi_do_bind(ads, p.name); + } + + ads_free_service_principal(&p); + + return status; +} + #endif /* HAVE_GGSAPI */ /* mapping between SASL mechanisms and functions */ -- cgit From 56766b1f3ed8463a6a5c07658b0c350e4942bc9d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 31 Jul 2007 12:27:25 +0000 Subject: r24103: add some useful debug messages, as not all LDAP libraries support wrapping hooks... metze (This used to be commit 581a1d3a20ffed42ccc7f35f163fd343ed12ccd3) --- source3/libads/sasl.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 0bc741c02a..fa9afd7869 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -251,7 +251,13 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) ads->ldap.out.sig_size = NTLMSSP_SIG_SIZE; ads->ldap.in.min = 4; ads->ldap.in.max = 0x0FFFFFFF; - ads_setup_sasl_wrapping(ads, &ads_sasl_ntlmssp_ops, ntlmssp_state); + status = ads_setup_sasl_wrapping(ads, &ads_sasl_ntlmssp_ops, ntlmssp_state); + if (!ADS_ERR_OK(status)) { + DEBUG(0, "ads_setup_sasl_wrapping() failed: %s\n", + ads_errstr(status))); + ntlmssp_end(&ntlmssp_state); + return status; + } } else { ntlmssp_end(&ntlmssp_state); } @@ -582,7 +588,12 @@ static ADS_STATUS ads_sasl_spnego_gsskrb5_bind(ADS_STRUCT *ads, const gss_name_t ads->ldap.out.sig_size = max_msg_size - ads->ldap.out.max; ads->ldap.in.min = 4; ads->ldap.in.max = max_msg_size; - ads_setup_sasl_wrapping(ads, &ads_sasl_gssapi_ops, context_handle); + status = ads_setup_sasl_wrapping(ads, &ads_sasl_gssapi_ops, context_handle); + if (!ADS_ERR_OK(status)) { + DEBUG(0, "ads_setup_sasl_wrapping() failed: %s\n", + ads_errstr(status))); + goto failed; + } /* make sure we don't free context_handle */ context_handle = GSS_C_NO_CONTEXT; } @@ -1059,7 +1070,12 @@ static ADS_STATUS ads_sasl_gssapi_do_bind(ADS_STRUCT *ads, const gss_name_t serv ads->ldap.out.sig_size = max_msg_size - ads->ldap.out.max; ads->ldap.in.min = 4; ads->ldap.in.max = max_msg_size; - ads_setup_sasl_wrapping(ads, &ads_sasl_gssapi_ops, context_handle); + status = ads_setup_sasl_wrapping(ads, &ads_sasl_gssapi_ops, context_handle); + if (!ADS_ERR_OK(status)) { + DEBUG(0, "ads_setup_sasl_wrapping() failed: %s\n", + ads_errstr(status))); + goto failed; + } /* make sure we don't free context_handle */ context_handle = GSS_C_NO_CONTEXT; } -- cgit From e1b117719602f8d52228e63c50021db72f629515 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 31 Jul 2007 12:30:37 +0000 Subject: r24104: fix the build, sorry... metze (This used to be commit a5e1f9fd293fab26d664a72ee652eb8ca72128b7) --- source3/libads/sasl.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index fa9afd7869..5c4006e769 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -126,6 +126,7 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) struct berval cred, *scred = NULL; int rc; NTSTATUS nt_status; + ADS_STATUS status; int turn = 1; uint32 features = 0; @@ -253,7 +254,7 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) ads->ldap.in.max = 0x0FFFFFFF; status = ads_setup_sasl_wrapping(ads, &ads_sasl_ntlmssp_ops, ntlmssp_state); if (!ADS_ERR_OK(status)) { - DEBUG(0, "ads_setup_sasl_wrapping() failed: %s\n", + DEBUG(0, ("ads_setup_sasl_wrapping() failed: %s\n", ads_errstr(status))); ntlmssp_end(&ntlmssp_state); return status; @@ -590,7 +591,7 @@ static ADS_STATUS ads_sasl_spnego_gsskrb5_bind(ADS_STRUCT *ads, const gss_name_t ads->ldap.in.max = max_msg_size; status = ads_setup_sasl_wrapping(ads, &ads_sasl_gssapi_ops, context_handle); if (!ADS_ERR_OK(status)) { - DEBUG(0, "ads_setup_sasl_wrapping() failed: %s\n", + DEBUG(0, ("ads_setup_sasl_wrapping() failed: %s\n", ads_errstr(status))); goto failed; } @@ -1072,7 +1073,7 @@ static ADS_STATUS ads_sasl_gssapi_do_bind(ADS_STRUCT *ads, const gss_name_t serv ads->ldap.in.max = max_msg_size; status = ads_setup_sasl_wrapping(ads, &ads_sasl_gssapi_ops, context_handle); if (!ADS_ERR_OK(status)) { - DEBUG(0, "ads_setup_sasl_wrapping() failed: %s\n", + DEBUG(0, ("ads_setup_sasl_wrapping() failed: %s\n", ads_errstr(status))); goto failed; } -- cgit From d2900ddf1121f777ec8b28620fa93637b58e2a59 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 2 Aug 2007 15:11:37 +0000 Subject: r24128: fix double free in error path metze (This used to be commit 29e2d8e044c9213643a2f5f29891ce853a839347) --- source3/libads/sasl.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 5c4006e769..c727c8b50a 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -962,11 +962,10 @@ static ADS_STATUS ads_sasl_gssapi_do_bind(ADS_STRUCT *ads, const gss_name_t serv &output_token, &ret_flags, NULL); - - if (input_token.value) { - gss_release_buffer(&minor_status, &input_token); + if (scred) { + ber_bvfree(scred); + scred = NULL; } - if (gss_rc && gss_rc != GSS_S_CONTINUE_NEEDED) { status = ADS_ERROR_GSS(gss_rc, minor_status); goto failed; @@ -999,13 +998,15 @@ static ADS_STATUS ads_sasl_gssapi_do_bind(ADS_STRUCT *ads, const gss_name_t serv gss_rc = gss_unwrap(&minor_status,context_handle,&input_token,&output_token, &conf_state,NULL); + if (scred) { + ber_bvfree(scred); + scred = NULL; + } if (gss_rc) { status = ADS_ERROR_GSS(gss_rc, minor_status); goto failed; } - gss_release_buffer(&minor_status, &input_token); - p = (uint8 *)output_token.value; #if 0 -- cgit From cc8d70036477f30c6c9c8a6e37d1e2680107c0a6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 2 Aug 2007 17:41:47 +0000 Subject: r24131: - make it more clear what the different min and max fields mean - with the "GSSAPI" sasl mech the plain, sign or seal negotiation is independed from the req_flags and ret_flags - verify the server supports the wrapping type we want - better handling on negotiated buffer sizes metze (This used to be commit d0ec7323870ca16b28d458ff5f7dacce278b7d54) --- source3/libads/sasl.c | 77 ++++++++++++++++++++++++------------------ source3/libads/sasl_wrapping.c | 8 ++--- 2 files changed, 48 insertions(+), 37 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index c727c8b50a..bcd8833f30 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -247,11 +247,10 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) then the state will be kept by the signing engine */ if (ads->ldap.wrap_type > ADS_SASLWRAP_TYPE_PLAIN) { - ads->ldap.out.min = 4; - ads->ldap.out.max = 0x0FFFFFFF - NTLMSSP_SIG_SIZE; + ads->ldap.out.max_unwrapped = ADS_SASL_WRAPPING_OUT_MAX_WRAPPED - NTLMSSP_SIG_SIZE; ads->ldap.out.sig_size = NTLMSSP_SIG_SIZE; - ads->ldap.in.min = 4; - ads->ldap.in.max = 0x0FFFFFFF; + ads->ldap.in.min_wrapped = ads->ldap.out.sig_size; + ads->ldap.in.max_wrapped = ADS_SASL_WRAPPING_IN_MAX_WRAPPED; status = ads_setup_sasl_wrapping(ads, &ads_sasl_ntlmssp_ops, ntlmssp_state); if (!ADS_ERR_OK(status)) { DEBUG(0, ("ads_setup_sasl_wrapping() failed: %s\n", @@ -574,21 +573,20 @@ static ADS_STATUS ads_sasl_spnego_gsskrb5_bind(ADS_STRUCT *ads, const gss_name_t } if (ads->ldap.wrap_type > ADS_SASLWRAP_TYPE_PLAIN) { - uint32 max_msg_size = 0x0A000000; + uint32 max_msg_size = ADS_SASL_WRAPPING_OUT_MAX_WRAPPED; gss_rc = gss_wrap_size_limit(&minor_status, context_handle, (ads->ldap.wrap_type == ADS_SASLWRAP_TYPE_SEAL), GSS_C_QOP_DEFAULT, - max_msg_size, &ads->ldap.out.max); + max_msg_size, &ads->ldap.out.max_unwrapped); if (gss_rc) { status = ADS_ERROR_GSS(gss_rc, minor_status); goto failed; } - ads->ldap.out.min = 4; - ads->ldap.out.sig_size = max_msg_size - ads->ldap.out.max; - ads->ldap.in.min = 4; - ads->ldap.in.max = max_msg_size; + ads->ldap.out.sig_size = max_msg_size - ads->ldap.out.max_unwrapped; + ads->ldap.in.min_wrapped = 0x2C; /* taken from a capture with LDAP unbind */ + ads->ldap.in.max_wrapped = max_msg_size; status = ads_setup_sasl_wrapping(ads, &ads_sasl_gssapi_ops, context_handle); if (!ADS_ERR_OK(status)) { DEBUG(0, ("ads_setup_sasl_wrapping() failed: %s\n", @@ -930,23 +928,19 @@ static ADS_STATUS ads_sasl_gssapi_do_bind(ADS_STRUCT *ads, const gss_name_t serv int i=0; int gss_rc, rc; uint8 *p; - uint32 max_msg_size = 0; + uint32 max_msg_size = ADS_SASL_WRAPPING_OUT_MAX_WRAPPED; + uint8 wrap_type = ADS_SASLWRAP_TYPE_PLAIN; ADS_STATUS status; input_token.value = NULL; input_token.length = 0; - req_flags = GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG; - switch (ads->ldap.wrap_type) { - case ADS_SASLWRAP_TYPE_SEAL: - req_flags |= GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG; - break; - case ADS_SASLWRAP_TYPE_SIGN: - req_flags |= GSS_C_INTEG_FLAG; - break; - case ADS_SASLWRAP_TYPE_PLAIN: - break; - } + /* + * Note: here we always ask the gssapi for sign and seal + * as this is negotiated later after the mutal + * authentication + */ + req_flags = GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG | GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG; for (i=0; i < MAX_GSS_PASSES; i++) { gss_rc = gss_init_sec_context(&minor_status, @@ -1014,20 +1008,37 @@ static ADS_STATUS ads_sasl_gssapi_do_bind(ADS_STRUCT *ads, const gss_name_t serv #endif if (p) { - max_msg_size = (p[1]<<16) | (p[2]<<8) | p[3]; + wrap_type = CVAL(p,0); + SCVAL(p,0,0); + max_msg_size = RIVAL(p,0); } gss_release_buffer(&minor_status, &output_token); + if (!(wrap_type & ads->ldap.wrap_type)) { + /* + * the server doesn't supports the wrap + * type we want :-( + */ + DEBUG(0,("The ldap sasl wrap type doesn't match wanted[%d] server[%d]\n", + ads->ldap.wrap_type, wrap_type)); + DEBUGADD(0,("You may want to set the 'client ldap sasl wrapping' option\n")); + status = ADS_ERROR_NT(NT_STATUS_NOT_SUPPORTED); + goto failed; + } + + /* 0x58 is the minimum windows accepts */ + if (max_msg_size < 0x58) { + max_msg_size = 0x58; + } + output_token.length = 4; output_token.value = SMB_MALLOC(output_token.length); p = (uint8 *)output_token.value; - *p++ = ads->ldap.wrap_type; - /* choose the same size as the server gave us */ - *p++ = max_msg_size>>16; - *p++ = max_msg_size>>8; - *p++ = max_msg_size; + RSIVAL(p,0,max_msg_size); + SCVAL(p,0,ads->ldap.wrap_type); + /* * we used to add sprintf("dn:%s", ads->config.bind_path) here. * but using ads->config.bind_path is the wrong! It should be @@ -1062,16 +1073,15 @@ static ADS_STATUS ads_sasl_gssapi_do_bind(ADS_STRUCT *ads, const gss_name_t serv gss_rc = gss_wrap_size_limit(&minor_status, context_handle, (ads->ldap.wrap_type == ADS_SASLWRAP_TYPE_SEAL), GSS_C_QOP_DEFAULT, - max_msg_size, &ads->ldap.out.max); + max_msg_size, &ads->ldap.out.max_unwrapped); if (gss_rc) { status = ADS_ERROR_GSS(gss_rc, minor_status); goto failed; } - ads->ldap.out.min = 4; - ads->ldap.out.sig_size = max_msg_size - ads->ldap.out.max; - ads->ldap.in.min = 4; - ads->ldap.in.max = max_msg_size; + ads->ldap.out.sig_size = max_msg_size - ads->ldap.out.max_unwrapped; + ads->ldap.in.min_wrapped = 0x2C; /* taken from a capture with LDAP unbind */ + ads->ldap.in.max_wrapped = max_msg_size; status = ads_setup_sasl_wrapping(ads, &ads_sasl_gssapi_ops, context_handle); if (!ADS_ERR_OK(status)) { DEBUG(0, ("ads_setup_sasl_wrapping() failed: %s\n", @@ -1081,6 +1091,7 @@ static ADS_STATUS ads_sasl_gssapi_do_bind(ADS_STRUCT *ads, const gss_name_t serv /* make sure we don't free context_handle */ context_handle = GSS_C_NO_CONTEXT; } + failed: if (context_handle != GSS_C_NO_CONTEXT) diff --git a/source3/libads/sasl_wrapping.c b/source3/libads/sasl_wrapping.c index c620aae7ac..2bfa079235 100644 --- a/source3/libads/sasl_wrapping.c +++ b/source3/libads/sasl_wrapping.c @@ -42,7 +42,7 @@ static ber_slen_t ads_saslwrap_prepare_inbuf(ADS_STRUCT *ads) ads->ldap.in.ofs = 0; ads->ldap.in.needed = 0; ads->ldap.in.left = 0; - ads->ldap.in.size = 4 + ads->ldap.in.min; + ads->ldap.in.size = 4 + ads->ldap.in.min_wrapped; ads->ldap.in.buf = talloc_array(ads->ldap.mem_ctx, uint8, ads->ldap.in.size); if (!ads->ldap.in.buf) { @@ -99,11 +99,11 @@ static ber_slen_t ads_saslwrap_read(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t if (ads->ldap.in.ofs < 4) goto eagain; ads->ldap.in.needed = RIVAL(ads->ldap.in.buf, 0); - if (ads->ldap.in.needed > ads->ldap.in.max) { + if (ads->ldap.in.needed > ads->ldap.in.max_wrapped) { errno = EINVAL; return -1; } - if (ads->ldap.in.needed < ads->ldap.in.min) { + if (ads->ldap.in.needed < ads->ldap.in.min_wrapped) { errno = EINVAL; return -1; } @@ -208,7 +208,7 @@ static ber_slen_t ads_saslwrap_write(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_ return -1; } - rlen = MIN(len, ads->ldap.out.max); + rlen = MIN(len, ads->ldap.out.max_unwrapped); ret = ads_saslwrap_prepare_outbuf(ads, rlen); if (ret < 0) return ret; -- cgit From cdd140fe2774c1e65cdf43091a746ad2ef0fd3e7 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 3 Aug 2007 13:53:25 +0000 Subject: r24158: SE_GROUP_RESOURCE in the other_sids list apparently means a domain local group. Fix a typo in the PAC debugging routine (This used to be commit b0b66b2e7af133b199868b946fad70016e1cefbd) --- source3/libads/authdata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c index b19bec43c5..a76a7ca485 100644 --- a/source3/libads/authdata.c +++ b/source3/libads/authdata.c @@ -766,7 +766,7 @@ void dump_pac_logon_info(int lvl, PAC_LOGON_INFO *logon_info) SAFE_FREE(attr_string); } - DEBUGADD(lvl,("\tGroup Membership (Ressource Groups (SID History ?)):\n")); + DEBUGADD(lvl,("\tGroup Membership (Resource Groups (SID History ?)):\n")); for (i = 0; i < logon_info->info3.res_group_count; i++) { attr_string = pac_group_attr_string(logon_info->res_groups.group_membership[i].attrs); DEBUGADD(lvl,("\t\t%d: sid: %s-%d\n\t\t attr: 0x%x == %s\n", -- cgit From 8476d072d34ee8a9562aa99d628484926939ebdd Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 4 Aug 2007 10:25:27 +0000 Subject: r24166: Fix Coverity ID 391 (This used to be commit 461974d2cc18c729f152356a9c30cc776f288906) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 6c9bde24b0..f8c47ca5be 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2723,7 +2723,7 @@ ADS_STATUS ads_site_dn_for_machine(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const c if (*site_dn == NULL) { ads_msgfree(ads, res); ads_memfree(ads, dn); - ADS_ERROR(LDAP_NO_MEMORY); + return ADS_ERROR(LDAP_NO_MEMORY); } ads_memfree(ads, dn); -- cgit From bed0ea06936ba76deafd839c25a6abf438d63189 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 6 Aug 2007 13:48:57 +0000 Subject: r24251: Neverending fun: Heimdal doesn't accept all OIDs and gss_import_name() fails with GSS_S_BAD_NAMETYPE using this one. Use the GSS_KRB5_NT_PRINCIPAL_NAME OID instead (which works with at least MIT 1.6.1 and Heimdal 1.0.1). Guenther (This used to be commit f783b32b65ee50e3730ae2d039ca04c9fc5a201a) --- source3/libads/sasl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index bcd8833f30..fb4fb2132d 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -650,7 +650,7 @@ static ADS_STATUS ads_generate_service_principal(ADS_STRUCT *ads, #ifdef HAVE_GSSAPI gss_buffer_desc input_name; gss_OID_desc nt_principal = - {10, CONST_DISCARD(char *, "\052\206\110\206\367\022\001\002\002\002")}; + {10, CONST_DISCARD(char *, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x01")}; uint32 minor_status; int gss_rc; #endif -- cgit From 6ba2d944a0b5314564f077c6e896312b03cdd236 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 6 Aug 2007 14:03:11 +0000 Subject: r24252: Dump guid of msExchMailboxGuid when returned. Guenther (This used to be commit 1142f3df546cbf4780c6f54667f7ed31b1a7621b) --- source3/libads/ldap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index f8c47ca5be..b1a86ad3d3 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1902,6 +1902,7 @@ static BOOL ads_dump_field(ADS_STRUCT *ads, char *field, void **values, void *da {"tokenGroupsNoGCAcceptable", False, dump_sid}, {"tokengroupsGlobalandUniversal", False, dump_sid}, {"mS-DS-CreatorSID", False, dump_sid}, + {"msExchMailboxGuid", False, dump_guid}, {NULL, True, NULL} }; int i; -- cgit From 3e00e2e9cecb829edf0a1d780abe78346d13ed2f Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 14 Aug 2007 16:04:37 +0000 Subject: r24424: Fix the build. Guenther (This used to be commit 029bf26f8a571ae060f7be60fd3e8c61d86004f7) --- source3/libads/authdata.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c index a76a7ca485..793b9adb06 100644 --- a/source3/libads/authdata.c +++ b/source3/libads/authdata.c @@ -958,11 +958,11 @@ out: /**************************************************************** ****************************************************************/ - NTSTATUS kerberos_return_pac(TALLOC_CTX *mem_ctx, - const char *name, - const char *pass, - time_t time_offset, - PAC_DATA **pac_ret) +NTSTATUS kerberos_return_pac(TALLOC_CTX *mem_ctx, + const char *name, + const char *pass, + time_t time_offset, + PAC_DATA **pac_ret) { krb5_error_code ret; NTSTATUS status = NT_STATUS_INVALID_PARAMETER; -- cgit From 201f0e1ce405273ffc19d280f91d8eee17bdaaec Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 14 Aug 2007 19:47:57 +0000 Subject: r24432: Expand kerberos_return_pac() so that it can be used in winbindd. Guenther (This used to be commit e70bf0ecc3ec6d3ba8ba384024bbdf9a783072ea) --- source3/libads/authdata.c | 78 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 72 insertions(+), 6 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c index 793b9adb06..bbcd2db56a 100644 --- a/source3/libads/authdata.c +++ b/source3/libads/authdata.c @@ -962,6 +962,12 @@ NTSTATUS kerberos_return_pac(TALLOC_CTX *mem_ctx, const char *name, const char *pass, time_t time_offset, + time_t *expire_time, + time_t *renew_till_time, + const char *cache_name, + BOOL request_pac, + BOOL add_netbios_addr, + time_t renewable_time, PAC_DATA **pac_ret) { krb5_error_code ret; @@ -982,6 +988,10 @@ NTSTATUS kerberos_return_pac(TALLOC_CTX *mem_ctx, return NT_STATUS_INVALID_PARAMETER; } + if (cache_name) { + cc = cache_name; + } + if (!strchr_m(name, '@')) { auth_princ = talloc_asprintf(mem_ctx, "%s@%s", name, lp_realm()); @@ -997,18 +1007,41 @@ NTSTATUS kerberos_return_pac(TALLOC_CTX *mem_ctx, ret = kerberos_kinit_password_ext(auth_princ, pass, time_offset, - NULL, - NULL, + expire_time, + renew_till_time, cc, - True, - True, - 0, + request_pac, + add_netbios_addr, + renewable_time, &status); if (ret) { + DEBUG(1,("kinit failed for '%s' with: %s (%d)\n", + auth_princ, error_message(ret), ret)); /* status already set */ goto out; } + DEBUG(10,("got TGT for %s in %s\n", auth_princ, cc)); + if (expire_time) { + DEBUGADD(10,("\tvalid until: %s (%d)\n", + http_timestring(*expire_time), + (int)*expire_time)); + } + if (renew_till_time) { + DEBUGADD(10,("\trenewable till: %s (%d)\n", + http_timestring(*renew_till_time), + (int)*renew_till_time)); + } + + /* we cannot continue with krb5 when UF_DONT_REQUIRE_PREAUTH is set, + * in that case fallback to NTLM - gd */ + + if (expire_time && renew_till_time && + (*expire_time == 0) && (*renew_till_time == 0)) { + return NT_STATUS_INVALID_LOGON_TYPE; + } + + ret = cli_krb5_get_ticket(local_service, time_offset, &tkt, @@ -1017,6 +1050,8 @@ NTSTATUS kerberos_return_pac(TALLOC_CTX *mem_ctx, cc, NULL); if (ret) { + DEBUG(1,("failed to get ticket for %s: %s\n", + local_service, error_message(ret))); status = krb5_to_nt_status(ret); goto out; } @@ -1031,10 +1066,13 @@ NTSTATUS kerberos_return_pac(TALLOC_CTX *mem_ctx, &sesskey2, False); if (!NT_STATUS_IS_OK(status)) { + DEBUG(1,("ads_verify_ticket failed: %s\n", + nt_errstr(status))); goto out; } if (!pac_data) { + DEBUG(1,("no PAC\n")); status = NT_STATUS_INVALID_PARAMETER; goto out; } @@ -1042,7 +1080,9 @@ NTSTATUS kerberos_return_pac(TALLOC_CTX *mem_ctx, *pac_ret = pac_data; out: - ads_kdestroy(cc); + if (cc != cache_name) { + ads_kdestroy(cc); + } data_blob_free(&tkt); data_blob_free(&ap_rep); @@ -1061,6 +1101,12 @@ static NTSTATUS kerberos_return_pac_logon_info(TALLOC_CTX *mem_ctx, const char *name, const char *pass, time_t time_offset, + time_t *expire_time, + time_t *renew_till_time, + const char *cache_name, + BOOL request_pac, + BOOL add_netbios_addr, + time_t renewable_time, PAC_LOGON_INFO **logon_info) { NTSTATUS status; @@ -1071,17 +1117,25 @@ static NTSTATUS kerberos_return_pac_logon_info(TALLOC_CTX *mem_ctx, name, pass, time_offset, + expire_time, + renew_till_time, + cache_name, + request_pac, + add_netbios_addr, + renewable_time, &pac_data); if (!NT_STATUS_IS_OK(status)) { return status; } if (!pac_data) { + DEBUG(3,("no pac\n")); return NT_STATUS_INVALID_USER_BUFFER; } info = get_logon_info_from_pac(pac_data); if (!info) { + DEBUG(1,("no logon_info\n")); return NT_STATUS_INVALID_USER_BUFFER; } @@ -1097,6 +1151,12 @@ NTSTATUS kerberos_return_info3_from_pac(TALLOC_CTX *mem_ctx, const char *name, const char *pass, time_t time_offset, + time_t *expire_time, + time_t *renew_till_time, + const char *cache_name, + BOOL request_pac, + BOOL add_netbios_addr, + time_t renewable_time, NET_USER_INFO_3 **info3) { NTSTATUS status; @@ -1106,6 +1166,12 @@ NTSTATUS kerberos_return_info3_from_pac(TALLOC_CTX *mem_ctx, name, pass, time_offset, + expire_time, + renew_till_time, + cache_name, + request_pac, + add_netbios_addr, + renewable_time, &logon_info); if (!NT_STATUS_IS_OK(status)) { return status; -- cgit From d61c180e4903012a868c36e19473ccff5545976c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 24 Aug 2007 15:50:12 +0000 Subject: r24654: Adapt to coding conventions. Guenther (This used to be commit a669ac2bc45dc6f261a789050a021d625c083829) --- source3/libads/smb_krb5_locator.c | 46 +++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 21 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/smb_krb5_locator.c b/source3/libads/smb_krb5_locator.c index b5a6ffd453..6a90677262 100644 --- a/source3/libads/smb_krb5_locator.c +++ b/source3/libads/smb_krb5_locator.c @@ -1,18 +1,18 @@ -/* +/* Unix SMB/CIFS implementation. kerberos locator plugin Copyright (C) Guenther Deschner 2007 - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -92,7 +92,7 @@ static const char *family_name(int family) /** * Check input parameters, return KRB5_PLUGIN_NO_HANDLE for unsupported ones * - * @param svc + * @param svc * @param realm string * @param socktype integer * @param family integer @@ -163,7 +163,7 @@ static int smb_krb5_locator_lookup_sanity_check(enum locate_service_type svc, * @return krb5_error_code. */ -static krb5_error_code smb_krb5_locator_call_cbfunc(const char *name, +static krb5_error_code smb_krb5_locator_call_cbfunc(const char *name, const char *service, struct addrinfo *in, int (*cbfunc)(void *, int, struct sockaddr *), @@ -185,7 +185,7 @@ static krb5_error_code smb_krb5_locator_call_cbfunc(const char *name, continue; } - DEBUG(10,("smb_krb5_locator_lookup: got ret: %s (%d)\n", + DEBUG(10,("smb_krb5_locator_lookup: got ret: %s (%d)\n", gai_strerror(ret), ret)); #ifdef KRB5_PLUGIN_NO_HANDLE return KRB5_PLUGIN_NO_HANDLE; @@ -196,7 +196,8 @@ static krb5_error_code smb_krb5_locator_call_cbfunc(const char *name, ret = cbfunc(cbdata, out->ai_socktype, out->ai_addr); if (ret) { - DEBUG(10,("smb_krb5_locator_lookup: failed to call callback: %s (%d)\n", + DEBUG(10,("smb_krb5_locator_lookup: " + "failed to call callback: %s (%d)\n", error_message(ret), ret)); } @@ -214,7 +215,7 @@ static krb5_error_code smb_krb5_locator_call_cbfunc(const char *name, * @return krb5_error_code. */ -krb5_error_code smb_krb5_locator_init(krb5_context context, +krb5_error_code smb_krb5_locator_init(krb5_context context, void **private_data) { setup_logging("smb_krb5_locator", True); @@ -270,18 +271,20 @@ krb5_error_code smb_krb5_locator_lookup(void *private_data, int count = 0; struct addrinfo aihints; char *saf_name = NULL; + const char *service = get_service_from_locate_service_type(svc); int i; DEBUG(10,("smb_krb5_locator_lookup: called for\n")); - DEBUGADD(10,("\tsvc: %s (%d), realm: %s\n", + DEBUGADD(10,("\tsvc: %s (%d), realm: %s\n", locate_service_type_name(svc), svc, realm)); - DEBUGADD(10,("\tsocktype: %s (%d), family: %s (%d)\n", + DEBUGADD(10,("\tsocktype: %s (%d), family: %s (%d)\n", socktype_name(socktype), socktype, family_name(family), family)); - ret = smb_krb5_locator_lookup_sanity_check(svc, realm, socktype, family); + ret = smb_krb5_locator_lookup_sanity_check(svc, realm, socktype, + family); if (ret) { - DEBUG(10,("smb_krb5_locator_lookup: returning ret: %s (%d)\n", + DEBUG(10,("smb_krb5_locator_lookup: returning ret: %s (%d)\n", error_message(ret), ret)); return ret; } @@ -290,22 +293,23 @@ krb5_error_code smb_krb5_locator_lookup(void *private_data, saf_name = saf_fetch(realm); if (!saf_name || strlen(saf_name) == 0) { - DEBUG(10,("smb_krb5_locator_lookup: no SAF name stored for %s\n", + DEBUG(10,("smb_krb5_locator_lookup: " + "no SAF name stored for %s\n", realm)); goto find_kdc; } - DEBUG(10,("smb_krb5_locator_lookup: got %s for %s from SAF cache\n", + DEBUG(10,("smb_krb5_locator_lookup: got %s for %s from SAF cache\n", saf_name, realm)); ZERO_STRUCT(aihints); - + aihints.ai_family = family; aihints.ai_socktype = socktype; - ret = smb_krb5_locator_call_cbfunc(saf_name, - get_service_from_locate_service_type(svc), - &aihints, + ret = smb_krb5_locator_call_cbfunc(saf_name, + service, + &aihints, cbfunc, cbdata); if (ret) { return ret; @@ -332,7 +336,7 @@ krb5_error_code smb_krb5_locator_lookup(void *private_data, if (!NT_STATUS_IS_OK(status)) { DEBUG(10,("smb_krb5_locator_lookup: got %s (%s)\n", - nt_errstr(status), + nt_errstr(status), error_message(nt_status_to_krb5(status)))); #ifdef KRB5_PLUGIN_NO_HANDLE return KRB5_PLUGIN_NO_HANDLE; @@ -356,7 +360,7 @@ krb5_error_code smb_krb5_locator_lookup(void *private_data, ret = smb_krb5_locator_call_cbfunc(host, port, - &aihints, + &aihints, cbfunc, cbdata); if (ret) { /* got error */ -- cgit From 22cf5a3f8086b8f823fa5c45bce4432df825b92c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 28 Aug 2007 14:27:48 +0000 Subject: r24739: With resolve_ads() allow to query for PDCs as well. Also add dns query functions to find GCs and DCs by GUID. Guenther (This used to be commit cc469157f6684ec507bf1c3a659fc36a53d304a1) --- source3/libads/dns.c | 137 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 109 insertions(+), 28 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/dns.c b/source3/libads/dns.c index 96cd54af06..02baec78fb 100644 --- a/source3/libads/dns.c +++ b/source3/libads/dns.c @@ -740,21 +740,23 @@ BOOL stored_sitename_changed(const char *realm, const char *sitename) Query with optional sitename. ********************************************************************/ -NTSTATUS ads_dns_query_internal(TALLOC_CTX *ctx, - const char *servicename, - const char *realm, - const char *sitename, - struct dns_rr_srv **dclist, - int *numdcs ) +static NTSTATUS ads_dns_query_internal(TALLOC_CTX *ctx, + const char *servicename, + const char *dc_pdc_gc_domains, + const char *realm, + const char *sitename, + struct dns_rr_srv **dclist, + int *numdcs ) { char *name; if (sitename) { - name = talloc_asprintf(ctx, "%s._tcp.%s._sites.dc._msdcs.%s", - servicename, sitename, realm ); - } else { - name = talloc_asprintf(ctx, "%s._tcp.dc._msdcs.%s", - servicename, realm ); - } + name = talloc_asprintf(ctx, "%s._tcp.%s._sites.%s._msdcs.%s", + servicename, sitename, + dc_pdc_gc_domains, realm); + } else { + name = talloc_asprintf(ctx, "%s._tcp.%s._msdcs.%s", + servicename, dc_pdc_gc_domains, realm); + } if (!name) { return NT_STATUS_NO_MEMORY; } @@ -766,14 +768,14 @@ NTSTATUS ads_dns_query_internal(TALLOC_CTX *ctx, ********************************************************************/ NTSTATUS ads_dns_query_dcs(TALLOC_CTX *ctx, - const char *realm, - const char *sitename, - struct dns_rr_srv **dclist, - int *numdcs ) + const char *realm, + const char *sitename, + struct dns_rr_srv **dclist, + int *numdcs ) { NTSTATUS status; - status = ads_dns_query_internal(ctx, "_ldap", realm, sitename, + status = ads_dns_query_internal(ctx, "_ldap", "dc", realm, sitename, dclist, numdcs); if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT) || @@ -781,10 +783,42 @@ NTSTATUS ads_dns_query_dcs(TALLOC_CTX *ctx, return status; } - if (sitename && !NT_STATUS_IS_OK(status)) { + if (sitename && + ((!NT_STATUS_IS_OK(status)) || + (NT_STATUS_IS_OK(status) && (numdcs == 0)))) { /* Sitename DNS query may have failed. Try without. */ - status = ads_dns_query_internal(ctx, "_ldap", realm, NULL, - dclist, numdcs); + status = ads_dns_query_internal(ctx, "_ldap", "dc", realm, + NULL, dclist, numdcs); + } + return status; +} + +/******************************************************************** + Query for AD GC's. +********************************************************************/ + +NTSTATUS ads_dns_query_gcs(TALLOC_CTX *ctx, + const char *realm, + const char *sitename, + struct dns_rr_srv **dclist, + int *numdcs ) +{ + NTSTATUS status; + + status = ads_dns_query_internal(ctx, "_ldap", "gc", realm, sitename, + dclist, numdcs); + + if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT) || + NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_REFUSED)) { + return status; + } + + if (sitename && + ((!NT_STATUS_IS_OK(status)) || + (NT_STATUS_IS_OK(status) && (numdcs == 0)))) { + /* Sitename DNS query may have failed. Try without. */ + status = ads_dns_query_internal(ctx, "_ldap", "gc", realm, + NULL, dclist, numdcs); } return status; } @@ -796,25 +830,72 @@ NTSTATUS ads_dns_query_dcs(TALLOC_CTX *ctx, ********************************************************************/ NTSTATUS ads_dns_query_kdcs(TALLOC_CTX *ctx, - const char *realm, - const char *sitename, - struct dns_rr_srv **dclist, - int *numdcs ) + const char *dns_forest_name, + const char *sitename, + struct dns_rr_srv **dclist, + int *numdcs ) { NTSTATUS status; - status = ads_dns_query_internal(ctx, "_kerberos", realm, sitename, - dclist, numdcs); + status = ads_dns_query_internal(ctx, "_kerberos", "dc", + dns_forest_name, sitename, dclist, + numdcs); if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT) || NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_REFUSED)) { return status; } - if (sitename && !NT_STATUS_IS_OK(status)) { + if (sitename && + ((!NT_STATUS_IS_OK(status)) || + (NT_STATUS_IS_OK(status) && (numdcs == 0)))) { /* Sitename DNS query may have failed. Try without. */ - status = ads_dns_query_internal(ctx, "_kerberos", realm, NULL, + status = ads_dns_query_internal(ctx, "_kerberos", "dc", + dns_forest_name, NULL, dclist, numdcs); } return status; } + +/******************************************************************** + Query for AD PDC. Sitename is obsolete here. +********************************************************************/ + +NTSTATUS ads_dns_query_pdc(TALLOC_CTX *ctx, + const char *dns_domain_name, + struct dns_rr_srv **dclist, + int *numdcs ) +{ + return ads_dns_query_internal(ctx, "_ldap", "pdc", dns_domain_name, + NULL, dclist, numdcs); +} + +/******************************************************************** + Query for AD DC by guid. Sitename is obsolete here. +********************************************************************/ + +NTSTATUS ads_dns_query_dcs_guid(TALLOC_CTX *ctx, + const char *dns_forest_name, + const struct GUID *domain_guid, + struct dns_rr_srv **dclist, + int *numdcs ) +{ + /*_ldap._tcp.DomainGuid.domains._msdcs.DnsForestName */ + + const char *domains; + const char *guid_string; + + guid_string = GUID_string(ctx, domain_guid); + if (!guid_string) { + return NT_STATUS_NO_MEMORY; + } + + /* little hack */ + domains = talloc_asprintf(ctx, "%s.domains", guid_string); + if (!domains) { + return NT_STATUS_NO_MEMORY; + } + + return ads_dns_query_internal(ctx, "_ldap", domains, dns_forest_name, + NULL, dclist, numdcs); +} -- cgit From 49e92d0d5611e4a6304a6de4a734208cbec757a6 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 28 Aug 2007 15:26:59 +0000 Subject: r24748: Remove all dependencies to samba internals and convert the krb5 locator plugin into a tiny winbindd DsGetDcName client. This still does not solve the case of using the locator from within winbindd itself but at least gencache.tdb and others are no longer corrupted. Guenther (This used to be commit 908e7963b8b2dd9b149f526a53dbb5dc7662bbef) --- source3/libads/smb_krb5_locator.c | 196 +++++++++++++++++++------------------- 1 file changed, 96 insertions(+), 100 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/smb_krb5_locator.c b/source3/libads/smb_krb5_locator.c index 6a90677262..91ea24b30f 100644 --- a/source3/libads/smb_krb5_locator.c +++ b/source3/libads/smb_krb5_locator.c @@ -17,9 +17,14 @@ along with this program. If not, see . */ -#include "includes.h" +#include "nsswitch/winbind_client.h" + +#ifndef DEBUG_KRB5 +#undef DEBUG_KRB5 +#endif #if defined(HAVE_KRB5) && defined(HAVE_KRB5_LOCATE_PLUGIN_H) +BOOL winbind_env_set( void ); #include @@ -42,6 +47,7 @@ static const char *get_service_from_locate_service_type(enum locate_service_type } +#ifdef DEBUG_KRB5 static const char *locate_service_type_name(enum locate_service_type svc) { switch (svc) { @@ -88,6 +94,7 @@ static const char *family_name(int family) } return "unknown"; } +#endif /** * Check input parameters, return KRB5_PLUGIN_NO_HANDLE for unsupported ones @@ -185,8 +192,12 @@ static krb5_error_code smb_krb5_locator_call_cbfunc(const char *name, continue; } - DEBUG(10,("smb_krb5_locator_lookup: got ret: %s (%d)\n", - gai_strerror(ret), ret)); +#ifdef DEBUG_KRB5 + fprintf(stderr, "[%5u]: smb_krb5_locator_lookup: " + "getaddrinfo failed: %s (%d)\n", + (unsigned int)getpid(), gai_strerror(ret), ret); +#endif + #ifdef KRB5_PLUGIN_NO_HANDLE return KRB5_PLUGIN_NO_HANDLE; #else @@ -195,11 +206,13 @@ static krb5_error_code smb_krb5_locator_call_cbfunc(const char *name, } ret = cbfunc(cbdata, out->ai_socktype, out->ai_addr); +#ifdef DEBUG_KRB5 if (ret) { - DEBUG(10,("smb_krb5_locator_lookup: " + fprintf(stderr, "[%5u]: smb_krb5_locator_lookup: " "failed to call callback: %s (%d)\n", - error_message(ret), ret)); + (unsigned int)getpid(), error_message(ret), ret); } +#endif freeaddrinfo(out); @@ -218,12 +231,6 @@ static krb5_error_code smb_krb5_locator_call_cbfunc(const char *name, krb5_error_code smb_krb5_locator_init(krb5_context context, void **private_data) { - setup_logging("smb_krb5_locator", True); - load_case_tables(); - lp_load(dyn_CONFIGFILE,True,False,False,True); - - DEBUG(10,("smb_krb5_locator_init: called\n")); - return 0; } @@ -237,9 +244,44 @@ krb5_error_code smb_krb5_locator_init(krb5_context context, void smb_krb5_locator_close(void *private_data) { - DEBUG(10,("smb_krb5_locator_close: called\n")); + return; +} + - /* gfree_all(); */ +static int ask_winbind(const char *realm, char **dcname) +{ + NSS_STATUS status; + struct winbindd_request request; + struct winbindd_response response; + + ZERO_STRUCT(request); + ZERO_STRUCT(response); + + request.flags = 0x40020600; + /* DS_KDC_REQUIRED | + DS_IS_DNS_NAME | + DS_RETURN_DNS_NAME | + DS_IP_REQUIRED */ + + strncpy(request.domain_name, realm, + sizeof(request.domain_name)-1); + + status = winbindd_request_response(WINBINDD_DSGETDCNAME, + &request, &response); + if (status != NSS_STATUS_SUCCESS) { +#ifdef DEBUG_KRB5 + fprintf(stderr,"[%5u]: smb_krb5_locator_lookup: failed with: %s\n", + (unsigned int)getpid(), nss_err_str(status)); +#endif + return False; + } + + *dcname = strdup(response.data.dc_name); + if (!*dcname) { + return False; + } + + return True; } /** @@ -264,111 +306,65 @@ krb5_error_code smb_krb5_locator_lookup(void *private_data, int (*cbfunc)(void *, int, struct sockaddr *), void *cbdata) { - NTSTATUS status; krb5_error_code ret; - char *sitename = NULL; - struct ip_service *ip_list; - int count = 0; struct addrinfo aihints; - char *saf_name = NULL; + char *kdc_name = NULL; const char *service = get_service_from_locate_service_type(svc); - int i; - DEBUG(10,("smb_krb5_locator_lookup: called for\n")); - DEBUGADD(10,("\tsvc: %s (%d), realm: %s\n", - locate_service_type_name(svc), svc, realm)); - DEBUGADD(10,("\tsocktype: %s (%d), family: %s (%d)\n", - socktype_name(socktype), socktype, - family_name(family), family)); + ZERO_STRUCT(aihints); +#ifdef DEBUG_KRB5 + fprintf(stderr,"[%5u]: smb_krb5_locator_lookup: called for '%s' " + "svc: '%s' (%d) " + "socktype: '%s' (%d), family: '%s' (%d)\n", + (unsigned int)getpid(), realm, + locate_service_type_name(svc), svc, + socktype_name(socktype), socktype, + family_name(family), family); +#endif ret = smb_krb5_locator_lookup_sanity_check(svc, realm, socktype, family); if (ret) { - DEBUG(10,("smb_krb5_locator_lookup: returning ret: %s (%d)\n", - error_message(ret), ret)); - return ret; - } - - /* first try to fetch from SAF cache */ - - saf_name = saf_fetch(realm); - if (!saf_name || strlen(saf_name) == 0) { - DEBUG(10,("smb_krb5_locator_lookup: " - "no SAF name stored for %s\n", - realm)); - goto find_kdc; - } - - DEBUG(10,("smb_krb5_locator_lookup: got %s for %s from SAF cache\n", - saf_name, realm)); - - ZERO_STRUCT(aihints); - - aihints.ai_family = family; - aihints.ai_socktype = socktype; - - ret = smb_krb5_locator_call_cbfunc(saf_name, - service, - &aihints, - cbfunc, cbdata); - if (ret) { +#ifdef DEBUG_KRB5 + fprintf(stderr, "[%5u]: smb_krb5_locator_lookup: " + "returning ret: %s (%d)\n", + (unsigned int)getpid(), error_message(ret), ret); +#endif return ret; } - return 0; - - find_kdc: - - /* now try to find via site-aware DNS SRV query */ - - sitename = sitename_fetch(realm); - status = get_kdc_list(realm, sitename, &ip_list, &count); - - /* if we didn't found any KDCs on our site go to the main list */ - - if (NT_STATUS_IS_OK(status) && sitename && (count == 0)) { - SAFE_FREE(ip_list); - SAFE_FREE(sitename); - status = get_kdc_list(realm, NULL, &ip_list, &count); - } - - SAFE_FREE(sitename); + if (!winbind_env_set()) { + if (!ask_winbind(realm, &kdc_name)) { +#ifdef DEBUG_KRB5 + fprintf(stderr, "[%5u]: smb_krb5_locator_lookup: " + "failed to query winbindd\n", + (unsigned int)getpid()); +#endif - if (!NT_STATUS_IS_OK(status)) { - DEBUG(10,("smb_krb5_locator_lookup: got %s (%s)\n", - nt_errstr(status), - error_message(nt_status_to_krb5(status)))); #ifdef KRB5_PLUGIN_NO_HANDLE - return KRB5_PLUGIN_NO_HANDLE; + return KRB5_PLUGIN_NO_HANDLE; #else - return KRB5_KDC_UNREACH; /* Heimdal */ + return KRB5_KDC_UNREACH; /* Heimdal */ #endif - } - - for (i=0; i Date: Tue, 28 Aug 2007 16:39:03 +0000 Subject: r24752: Make sure to return properly when the locator is called from within winbindd. Guenther (This used to be commit 6cf7187e88b4d4c1dfe90fcab459e39a0dbd3a11) --- source3/libads/smb_krb5_locator.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/smb_krb5_locator.c b/source3/libads/smb_krb5_locator.c index 91ea24b30f..33f2a414d0 100644 --- a/source3/libads/smb_krb5_locator.c +++ b/source3/libads/smb_krb5_locator.c @@ -340,16 +340,12 @@ krb5_error_code smb_krb5_locator_lookup(void *private_data, "failed to query winbindd\n", (unsigned int)getpid()); #endif - -#ifdef KRB5_PLUGIN_NO_HANDLE - return KRB5_PLUGIN_NO_HANDLE; -#else - return KRB5_KDC_UNREACH; /* Heimdal */ -#endif + goto failed; } } else { /* FIXME: here comes code for locator being called from within * winbind */ + goto failed; } #ifdef DEBUG_KRB5 fprintf(stderr, "[%5u]: smb_krb5_locator_lookup: " @@ -367,6 +363,13 @@ krb5_error_code smb_krb5_locator_lookup(void *private_data, SAFE_FREE(kdc_name); return ret; + + failed: +#ifdef KRB5_PLUGIN_NO_HANDLE + return KRB5_PLUGIN_NO_HANDLE; +#else + return KRB5_KDC_UNREACH; /* Heimdal */ +#endif } #ifdef HEIMDAL_KRB5_LOCATE_PLUGIN_H -- cgit From 60fb367fd94c19889ec4909b23c3e21dcda2e7d5 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 29 Aug 2007 10:12:43 +0000 Subject: r24769: Merge error handling for locator plugin. Guenther (This used to be commit b83626676ca37437e62b826923fbd1d985eb7ce6) --- source3/libads/smb_krb5_locator.c | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/smb_krb5_locator.c b/source3/libads/smb_krb5_locator.c index 33f2a414d0..5f90c71a2b 100644 --- a/source3/libads/smb_krb5_locator.c +++ b/source3/libads/smb_krb5_locator.c @@ -24,10 +24,14 @@ #endif #if defined(HAVE_KRB5) && defined(HAVE_KRB5_LOCATE_PLUGIN_H) -BOOL winbind_env_set( void ); +BOOL winbind_env_set(void); #include +#ifndef KRB5_PLUGIN_NO_HANDLE +#define KRB5_PLUGIN_NO_HANDLE KRB5_KDC_UNREACH /* Heimdal */ +#endif + static const char *get_service_from_locate_service_type(enum locate_service_type svc) { switch (svc) { @@ -123,11 +127,7 @@ static int smb_krb5_locator_lookup_sanity_check(enum locate_service_type svc, break; case locate_service_kadmin: case locate_service_krb524: -#ifdef KRB5_PLUGIN_NO_HANDLE return KRB5_PLUGIN_NO_HANDLE; -#else - return KRB5_KDC_UNREACH; /* Heimdal */ -#endif default: return EINVAL; } @@ -137,11 +137,7 @@ static int smb_krb5_locator_lookup_sanity_check(enum locate_service_type svc, case AF_INET: break; case AF_INET6: /* not yet */ -#ifdef KRB5_PLUGIN_NO_HANDLE return KRB5_PLUGIN_NO_HANDLE; -#else - return KRB5_KDC_UNREACH; /* Heimdal */ -#endif default: return EINVAL; } @@ -198,11 +194,7 @@ static krb5_error_code smb_krb5_locator_call_cbfunc(const char *name, (unsigned int)getpid(), gai_strerror(ret), ret); #endif -#ifdef KRB5_PLUGIN_NO_HANDLE return KRB5_PLUGIN_NO_HANDLE; -#else - return KRB5_KDC_UNREACH; /* Heimdal */ -#endif } ret = cbfunc(cbdata, out->ai_socktype, out->ai_addr); @@ -365,11 +357,7 @@ krb5_error_code smb_krb5_locator_lookup(void *private_data, return ret; failed: -#ifdef KRB5_PLUGIN_NO_HANDLE return KRB5_PLUGIN_NO_HANDLE; -#else - return KRB5_KDC_UNREACH; /* Heimdal */ -#endif } #ifdef HEIMDAL_KRB5_LOCATE_PLUGIN_H -- cgit From 647abf0a7b46a10c25e4d147dca2c4885b3ada7c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 30 Aug 2007 15:39:51 +0000 Subject: r24804: As a temporary workaround, also try to guess the server's principal in the "not_defined_in_RFC4178@please_ignore" case to make at least LDAP SASL binds succeed with windows server 2008. Guenther (This used to be commit f5b3de4d3069eaa750240e3422bac5cb169b6c0a) --- source3/libads/sasl.c | 53 +++++++++++----------------------------------- source3/libads/util.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 41 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index fb4fb2132d..3752d3c2ac 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -657,52 +657,23 @@ static ADS_STATUS ads_generate_service_principal(ADS_STRUCT *ads, ZERO_STRUCTP(p); - /* I've seen a child Windows 2000 domain not send - the principal name back in the first round of + /* I've seen a child Windows 2000 domain not send + the principal name back in the first round of the SASL bind reply. So we guess based on server name and realm. --jerry */ - if (given_principal) { - p->string = SMB_STRDUP(given_principal); - if (!p->string) { - return ADS_ERROR(LDAP_NO_MEMORY); - } - } else if (ads->server.realm && ads->server.ldap_server) { - char *server, *server_realm; - - server = SMB_STRDUP(ads->server.ldap_server); - server_realm = SMB_STRDUP(ads->server.realm); - - if (!server || !server_realm) { - return ADS_ERROR(LDAP_NO_MEMORY); - } - - strlower_m(server); - strupper_m(server_realm); - asprintf(&p->string, "ldap/%s@%s", server, server_realm); - - SAFE_FREE(server); - SAFE_FREE(server_realm); - - if (!p->string) { - return ADS_ERROR(LDAP_NO_MEMORY); - } - } else if (ads->config.realm && ads->config.ldap_server_name) { - char *server, *server_realm; + /* Also try best guess when we get the w2k8 ignore + principal back - gd */ - server = SMB_STRDUP(ads->config.ldap_server_name); - server_realm = SMB_STRDUP(ads->config.realm); + if (!given_principal || + strequal(given_principal, ADS_IGNORE_PRINCIPAL)) { - if (!server || !server_realm) { - return ADS_ERROR(LDAP_NO_MEMORY); + status = ads_guess_service_principal(ads, given_principal, + &p->string); + if (!ADS_ERR_OK(status)) { + return status; } - - strlower_m(server); - strupper_m(server_realm); - asprintf(&p->string, "ldap/%s@%s", server, server_realm); - - SAFE_FREE(server); - SAFE_FREE(server_realm); - + } else { + p->string = SMB_STRDUP(given_principal); if (!p->string) { return ADS_ERROR(LDAP_NO_MEMORY); } diff --git a/source3/libads/util.c b/source3/libads/util.c index 2fb9fa81b4..a0c9d8f4c4 100644 --- a/source3/libads/util.c +++ b/source3/libads/util.c @@ -51,4 +51,62 @@ failed: SAFE_FREE(password); return ret; } + +ADS_STATUS ads_guess_service_principal(ADS_STRUCT *ads, + const char *given_principal, + char **returned_principal) +{ + char *princ = NULL; + + if (ads->server.realm && ads->server.ldap_server) { + char *server, *server_realm; + + server = SMB_STRDUP(ads->server.ldap_server); + server_realm = SMB_STRDUP(ads->server.realm); + + if (!server || !server_realm) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + + strlower_m(server); + strupper_m(server_realm); + asprintf(&princ, "ldap/%s@%s", server, server_realm); + + SAFE_FREE(server); + SAFE_FREE(server_realm); + + if (!princ) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + } else if (ads->config.realm && ads->config.ldap_server_name) { + char *server, *server_realm; + + server = SMB_STRDUP(ads->config.ldap_server_name); + server_realm = SMB_STRDUP(ads->config.realm); + + if (!server || !server_realm) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + + strlower_m(server); + strupper_m(server_realm); + asprintf(&princ, "ldap/%s@%s", server, server_realm); + + SAFE_FREE(server); + SAFE_FREE(server_realm); + + if (!princ) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + } + + if (!princ) { + return ADS_ERROR(LDAP_PARAM_ERROR); + } + + *returned_principal = princ; + + return ADS_SUCCESS; +} + #endif -- cgit From dbdc0fecb6f5491cb36e93e5f39df2d89f611e17 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 31 Aug 2007 12:18:21 +0000 Subject: r24832: In the winbind-locator recursion case, try to pick up the kdc from the environment. Guenther (This used to be commit 7f42fe4e08c0899f5e8addbc5135d87af193ee68) --- source3/libads/smb_krb5_locator.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/smb_krb5_locator.c b/source3/libads/smb_krb5_locator.c index 5f90c71a2b..5de080c7ba 100644 --- a/source3/libads/smb_krb5_locator.c +++ b/source3/libads/smb_krb5_locator.c @@ -335,9 +335,28 @@ krb5_error_code smb_krb5_locator_lookup(void *private_data, goto failed; } } else { - /* FIXME: here comes code for locator being called from within - * winbind */ - goto failed; + const char *env = NULL; + char *var = NULL; + if (asprintf(&var, "%s_%s", + WINBINDD_LOCATOR_KDC_ADDRESS, realm) == -1) { + goto failed; + } + env = getenv(var); + if (!env) { +#ifdef DEBUG_KRB5 + fprintf(stderr, "[%5u]: smb_krb5_locator_lookup: " + "failed to get kdc from env %s\n", + (unsigned int)getpid(), var); +#endif + free(var); + goto failed; + } + free(var); + + kdc_name = strdup(env); + if (!kdc_name) { + goto failed; + } } #ifdef DEBUG_KRB5 fprintf(stderr, "[%5u]: smb_krb5_locator_lookup: " -- cgit From 55b59eb80b8d9268f0e21cbec9d878f99704f547 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 31 Aug 2007 12:21:18 +0000 Subject: r24833: Move locator to nsswitch (does not belong to libads anymore). Guenther (This used to be commit af90c6949c929c82d4390b2f87a420bd598275dd) --- source3/libads/smb_krb5_locator.c | 395 -------------------------------------- 1 file changed, 395 deletions(-) delete mode 100644 source3/libads/smb_krb5_locator.c (limited to 'source3/libads') diff --git a/source3/libads/smb_krb5_locator.c b/source3/libads/smb_krb5_locator.c deleted file mode 100644 index 5de080c7ba..0000000000 --- a/source3/libads/smb_krb5_locator.c +++ /dev/null @@ -1,395 +0,0 @@ -/* - Unix SMB/CIFS implementation. - kerberos locator plugin - Copyright (C) Guenther Deschner 2007 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "nsswitch/winbind_client.h" - -#ifndef DEBUG_KRB5 -#undef DEBUG_KRB5 -#endif - -#if defined(HAVE_KRB5) && defined(HAVE_KRB5_LOCATE_PLUGIN_H) -BOOL winbind_env_set(void); - -#include - -#ifndef KRB5_PLUGIN_NO_HANDLE -#define KRB5_PLUGIN_NO_HANDLE KRB5_KDC_UNREACH /* Heimdal */ -#endif - -static const char *get_service_from_locate_service_type(enum locate_service_type svc) -{ - switch (svc) { - case locate_service_kdc: - case locate_service_master_kdc: - return "88"; - case locate_service_kadmin: - case locate_service_krb524: - /* not supported */ - return NULL; - case locate_service_kpasswd: - return "464"; - default: - break; - } - return NULL; - -} - -#ifdef DEBUG_KRB5 -static const char *locate_service_type_name(enum locate_service_type svc) -{ - switch (svc) { - case locate_service_kdc: - return "locate_service_kdc"; - case locate_service_master_kdc: - return "locate_service_master_kdc"; - case locate_service_kadmin: - return "locate_service_kadmin"; - case locate_service_krb524: - return "locate_service_krb524"; - case locate_service_kpasswd: - return "locate_service_kpasswd"; - default: - break; - } - return NULL; -} - -static const char *socktype_name(int socktype) -{ - switch (socktype) { - case SOCK_STREAM: - return "SOCK_STREAM"; - case SOCK_DGRAM: - return "SOCK_DGRAM"; - default: - break; - } - return "unknown"; -} - -static const char *family_name(int family) -{ - switch (family) { - case AF_UNSPEC: - return "AF_UNSPEC"; - case AF_INET: - return "AF_INET"; - case AF_INET6: - return "AF_INET6"; - default: - break; - } - return "unknown"; -} -#endif - -/** - * Check input parameters, return KRB5_PLUGIN_NO_HANDLE for unsupported ones - * - * @param svc - * @param realm string - * @param socktype integer - * @param family integer - * - * @return integer. - */ - -static int smb_krb5_locator_lookup_sanity_check(enum locate_service_type svc, - const char *realm, - int socktype, - int family) -{ - if (!realm || strlen(realm) == 0) { - return EINVAL; - } - - switch (svc) { - case locate_service_kdc: - case locate_service_master_kdc: - case locate_service_kpasswd: - break; - case locate_service_kadmin: - case locate_service_krb524: - return KRB5_PLUGIN_NO_HANDLE; - default: - return EINVAL; - } - - switch (family) { - case AF_UNSPEC: - case AF_INET: - break; - case AF_INET6: /* not yet */ - return KRB5_PLUGIN_NO_HANDLE; - default: - return EINVAL; - } - - switch (socktype) { - case SOCK_STREAM: - case SOCK_DGRAM: - case 0: /* Heimdal uses that */ - break; - default: - return EINVAL; - } - - return 0; -} - -/** - * Try to get addrinfo for a given host and call the krb5 callback - * - * @param name string - * @param service string - * @param in struct addrinfo hint - * @param cbfunc krb5 callback function - * @param cbdata void pointer cbdata - * - * @return krb5_error_code. - */ - -static krb5_error_code smb_krb5_locator_call_cbfunc(const char *name, - const char *service, - struct addrinfo *in, - int (*cbfunc)(void *, int, struct sockaddr *), - void *cbdata) -{ - struct addrinfo *out; - int ret; - int count = 3; - - while (count) { - - ret = getaddrinfo(name, service, in, &out); - if (ret == 0) { - break; - } - - if (ret == EAI_AGAIN) { - count--; - continue; - } - -#ifdef DEBUG_KRB5 - fprintf(stderr, "[%5u]: smb_krb5_locator_lookup: " - "getaddrinfo failed: %s (%d)\n", - (unsigned int)getpid(), gai_strerror(ret), ret); -#endif - - return KRB5_PLUGIN_NO_HANDLE; - } - - ret = cbfunc(cbdata, out->ai_socktype, out->ai_addr); -#ifdef DEBUG_KRB5 - if (ret) { - fprintf(stderr, "[%5u]: smb_krb5_locator_lookup: " - "failed to call callback: %s (%d)\n", - (unsigned int)getpid(), error_message(ret), ret); - } -#endif - - freeaddrinfo(out); - - return ret; -} - -/** - * PUBLIC INTERFACE: locate init - * - * @param context krb5_context - * @param privata_data pointer to private data pointer - * - * @return krb5_error_code. - */ - -krb5_error_code smb_krb5_locator_init(krb5_context context, - void **private_data) -{ - return 0; -} - -/** - * PUBLIC INTERFACE: close locate - * - * @param private_data pointer to private data - * - * @return void. - */ - -void smb_krb5_locator_close(void *private_data) -{ - return; -} - - -static int ask_winbind(const char *realm, char **dcname) -{ - NSS_STATUS status; - struct winbindd_request request; - struct winbindd_response response; - - ZERO_STRUCT(request); - ZERO_STRUCT(response); - - request.flags = 0x40020600; - /* DS_KDC_REQUIRED | - DS_IS_DNS_NAME | - DS_RETURN_DNS_NAME | - DS_IP_REQUIRED */ - - strncpy(request.domain_name, realm, - sizeof(request.domain_name)-1); - - status = winbindd_request_response(WINBINDD_DSGETDCNAME, - &request, &response); - if (status != NSS_STATUS_SUCCESS) { -#ifdef DEBUG_KRB5 - fprintf(stderr,"[%5u]: smb_krb5_locator_lookup: failed with: %s\n", - (unsigned int)getpid(), nss_err_str(status)); -#endif - return False; - } - - *dcname = strdup(response.data.dc_name); - if (!*dcname) { - return False; - } - - return True; -} - -/** - * PUBLIC INTERFACE: locate lookup - * - * @param private_data pointer to private data - * @param svc enum locate_service_type. - * @param realm string - * @param socktype integer - * @param family integer - * @param cbfunc callback function to send back entries - * @param cbdata void pointer to cbdata - * - * @return krb5_error_code. - */ - -krb5_error_code smb_krb5_locator_lookup(void *private_data, - enum locate_service_type svc, - const char *realm, - int socktype, - int family, - int (*cbfunc)(void *, int, struct sockaddr *), - void *cbdata) -{ - krb5_error_code ret; - struct addrinfo aihints; - char *kdc_name = NULL; - const char *service = get_service_from_locate_service_type(svc); - - ZERO_STRUCT(aihints); - -#ifdef DEBUG_KRB5 - fprintf(stderr,"[%5u]: smb_krb5_locator_lookup: called for '%s' " - "svc: '%s' (%d) " - "socktype: '%s' (%d), family: '%s' (%d)\n", - (unsigned int)getpid(), realm, - locate_service_type_name(svc), svc, - socktype_name(socktype), socktype, - family_name(family), family); -#endif - ret = smb_krb5_locator_lookup_sanity_check(svc, realm, socktype, - family); - if (ret) { -#ifdef DEBUG_KRB5 - fprintf(stderr, "[%5u]: smb_krb5_locator_lookup: " - "returning ret: %s (%d)\n", - (unsigned int)getpid(), error_message(ret), ret); -#endif - return ret; - } - - if (!winbind_env_set()) { - if (!ask_winbind(realm, &kdc_name)) { -#ifdef DEBUG_KRB5 - fprintf(stderr, "[%5u]: smb_krb5_locator_lookup: " - "failed to query winbindd\n", - (unsigned int)getpid()); -#endif - goto failed; - } - } else { - const char *env = NULL; - char *var = NULL; - if (asprintf(&var, "%s_%s", - WINBINDD_LOCATOR_KDC_ADDRESS, realm) == -1) { - goto failed; - } - env = getenv(var); - if (!env) { -#ifdef DEBUG_KRB5 - fprintf(stderr, "[%5u]: smb_krb5_locator_lookup: " - "failed to get kdc from env %s\n", - (unsigned int)getpid(), var); -#endif - free(var); - goto failed; - } - free(var); - - kdc_name = strdup(env); - if (!kdc_name) { - goto failed; - } - } -#ifdef DEBUG_KRB5 - fprintf(stderr, "[%5u]: smb_krb5_locator_lookup: " - "got '%s' for '%s' from winbindd\n", (unsigned int)getpid(), - kdc_name, realm); -#endif - - aihints.ai_family = family; - aihints.ai_socktype = socktype; - - ret = smb_krb5_locator_call_cbfunc(kdc_name, - service, - &aihints, - cbfunc, cbdata); - SAFE_FREE(kdc_name); - - return ret; - - failed: - return KRB5_PLUGIN_NO_HANDLE; -} - -#ifdef HEIMDAL_KRB5_LOCATE_PLUGIN_H -#define SMB_KRB5_LOCATOR_SYMBOL_NAME resolve /* Heimdal */ -#else -#define SMB_KRB5_LOCATOR_SYMBOL_NAME service_locator /* MIT */ -#endif - -const krb5plugin_service_locate_ftable SMB_KRB5_LOCATOR_SYMBOL_NAME = { - 0, /* version */ - smb_krb5_locator_init, - smb_krb5_locator_close, - smb_krb5_locator_lookup, -}; - -#endif -- cgit From b20269287545926efff02b03642b1920d3afb3e4 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 31 Aug 2007 13:39:51 +0000 Subject: r24836: Initialize some uninitialized variables. This prevents a segfault when get_kdc_ip_string() is called with sitename == NULL. Michael (This used to be commit 58d31e057b57bc69a96e63aabba9aa1da5418d83) --- source3/libads/kerberos.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 2cf0577687..1b5ec88dcf 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -616,9 +616,11 @@ int kerberos_kinit_password(const char *principal, static char *get_kdc_ip_string(char *mem_ctx, const char *realm, const char *sitename, struct in_addr primary_ip) { - struct ip_service *ip_srv_site; - struct ip_service *ip_srv_nonsite; - int count_site, count_nonsite, i; + int i; + struct ip_service *ip_srv_site = NULL; + struct ip_service *ip_srv_nonsite = NULL; + int count_site = 0; + int count_nonsite = 0; char *kdc_str = talloc_asprintf(mem_ctx, "\tkdc = %s\n", inet_ntoa(primary_ip)); -- cgit From 9fa56b9ae9df53b60ff76f4ce08d720ff9a6fc36 Mon Sep 17 00:00:00 2001 From: Lars Müller Date: Sat, 8 Sep 2007 13:53:08 +0000 Subject: r25030: ip_srv_nonsite and count_nonsite are initialized in get_kdc_list() in any case. (This used to be commit 287604a1c7dc7dede4b278de92ad8233f597d0b6) --- source3/libads/kerberos.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 1b5ec88dcf..62a4f84e10 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -618,9 +618,9 @@ static char *get_kdc_ip_string(char *mem_ctx, const char *realm, const char *sit { int i; struct ip_service *ip_srv_site = NULL; - struct ip_service *ip_srv_nonsite = NULL; + struct ip_service *ip_srv_nonsite; int count_site = 0; - int count_nonsite = 0; + int count_nonsite; char *kdc_str = talloc_asprintf(mem_ctx, "\tkdc = %s\n", inet_ntoa(primary_ip)); -- cgit From cd45a258a7b66bd4919ac02a7f4bfbce9e4a195b Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 11 Sep 2007 14:56:43 +0000 Subject: r25080: Once we decrypted the packet but have timing problems (closkew, tkt not yet or no longer valid) there is no point to bother the keytab routines. Guenther (This used to be commit 7e4dcf8e7ecfd35668e86e22bed5a9280ae83959) --- source3/libads/kerberos_verify.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 99288b78e5..0edb5327d3 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -427,9 +427,16 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, /* Try secrets.tdb first and fallback to the krb5.keytab if necessary */ - auth_ok = ads_secrets_verify_ticket(context, auth_context, host_princ, + auth_ok = ads_secrets_verify_ticket(context, auth_context, host_princ, ticket, &tkt, &keyblock, &ret); + if (!auth_ok && + (ret == KRB5KRB_AP_ERR_TKT_NYV || + ret == KRB5KRB_AP_ERR_TKT_EXPIRED || + ret == KRB5KRB_AP_ERR_SKEW)) { + goto auth_failed; + } + if (!auth_ok && lp_use_kerberos_keytab()) { auth_ok = ads_keytab_verify_ticket(context, auth_context, ticket, &tkt, &keyblock, &ret); @@ -446,6 +453,7 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, #endif } + auth_failed: if (!auth_ok) { DEBUG(3,("ads_verify_ticket: krb5_rd_req with auth failed (%s)\n", error_message(ret))); -- cgit From dc58b03517f3cd68107e0645765725c5e9eb6fb1 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 11 Sep 2007 23:21:50 +0000 Subject: r25108: Make ifdef labyrinth in sasl code a bit more readable. Guenther (This used to be commit f31949ec3456134de474a0219a8cd5dcd15adea6) --- source3/libads/sasl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 3752d3c2ac..123ad491fb 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -603,7 +603,7 @@ failed: return status; } -#endif +#endif /* HAVE_GSSAPI */ #ifdef HAVE_KRB5 struct ads_service_principal { @@ -774,7 +774,7 @@ static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, #endif return ads_sasl_spnego_rawkrb5_bind(ads, p->string); } -#endif +#endif /* HAVE_KRB5 */ /* this performs a SASL/SPNEGO bind -- cgit From 1ef2464451ee64023173637fa03e703405dc8c85 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 11 Sep 2007 23:35:17 +0000 Subject: r25109: Remove obsolete argument from ads_guess_service_principal(). Guenther (This used to be commit 2dea9464bba76af4315a8207ccd3e564ec19d146) --- source3/libads/sasl.c | 5 ++--- source3/libads/util.c | 1 - 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 123ad491fb..a92bef7ecf 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -667,8 +667,7 @@ static ADS_STATUS ads_generate_service_principal(ADS_STRUCT *ads, if (!given_principal || strequal(given_principal, ADS_IGNORE_PRINCIPAL)) { - status = ads_guess_service_principal(ads, given_principal, - &p->string); + status = ads_guess_service_principal(ads, &p->string); if (!ADS_ERR_OK(status)) { return status; } @@ -1103,7 +1102,7 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) return status; } -#endif /* HAVE_GGSAPI */ +#endif /* HAVE_GSSAPI */ /* mapping between SASL mechanisms and functions */ static struct { diff --git a/source3/libads/util.c b/source3/libads/util.c index a0c9d8f4c4..af96c3e10a 100644 --- a/source3/libads/util.c +++ b/source3/libads/util.c @@ -53,7 +53,6 @@ failed: } ADS_STATUS ads_guess_service_principal(ADS_STRUCT *ads, - const char *given_principal, char **returned_principal) { char *princ = NULL; -- cgit From 1874c564db100600945c257b97d235757156dc24 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 13 Sep 2007 15:59:46 +0000 Subject: r25133: Fix sasl wrapping (for ldap sign&seal). The gss_import_name() broke as we switched from the internal MIT OID "gss_nt_krb5_principal" to "GSS_KRB5_NT_PRINCIPAL_NAME" and didn't switch from passing the krb5_principal (or better: a pointer to that, see MIT's "*HORRIBLE* bug") to pass the string principal directly. Jerry, Jeremy, neither I could figure out the need of passing in a krb5_principal at all nor could I reproduce the crash you were seeing. I sucessfully tested the code (now importing a string) with MIT 1.2.7, 1.3.6, 1.4.3, 1.5.1, 1.6.1 and Heimdal 0.7.2, 1.0, 1.0.1. Guenther (This used to be commit cb2dc715e33467c8b588161e816e72a948f6860c) --- source3/libads/sasl.c | 51 +++++---------------------------------------------- 1 file changed, 5 insertions(+), 46 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index a92bef7ecf..c4b383e026 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -607,9 +607,7 @@ failed: #ifdef HAVE_KRB5 struct ads_service_principal { - krb5_context ctx; char *string; - krb5_principal principal; #ifdef HAVE_GSSAPI gss_name_t name; #endif @@ -625,14 +623,6 @@ static void ads_free_service_principal(struct ads_service_principal *p) gss_release_name(&minor_status, &p->name); } #endif - if (p->principal) { - krb5_free_principal(p->ctx, p->principal); - } - - if (p->ctx) { - krb5_free_context(p->ctx); - } - ZERO_STRUCTP(p); } @@ -641,15 +631,10 @@ static ADS_STATUS ads_generate_service_principal(ADS_STRUCT *ads, struct ads_service_principal *p) { ADS_STATUS status; - krb5_enctype enc_types[] = { -#ifdef ENCTYPE_ARCFOUR_HMAC - ENCTYPE_ARCFOUR_HMAC, -#endif - ENCTYPE_DES_CBC_MD5, - ENCTYPE_NULL}; #ifdef HAVE_GSSAPI gss_buffer_desc input_name; - gss_OID_desc nt_principal = + /* GSS_KRB5_NT_PRINCIPAL_NAME */ + gss_OID_desc nt_principal = {10, CONST_DISCARD(char *, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x01")}; uint32 minor_status; int gss_rc; @@ -678,35 +663,9 @@ static ADS_STATUS ads_generate_service_principal(ADS_STRUCT *ads, } } - initialize_krb5_error_table(); - status = ADS_ERROR_KRB5(krb5_init_context(&p->ctx)); - if (!ADS_ERR_OK(status)) { - ads_free_service_principal(p); - return status; - } - status = ADS_ERROR_KRB5(krb5_set_default_tgs_ktypes(p->ctx, enc_types)); - if (!ADS_ERR_OK(status)) { - ads_free_service_principal(p); - return status; - } - status = ADS_ERROR_KRB5(smb_krb5_parse_name(p->ctx, p->string, &p->principal)); - if (!ADS_ERR_OK(status)) { - ads_free_service_principal(p); - return status; - } - #ifdef HAVE_GSSAPI - /* - * The MIT libraries have a *HORRIBLE* bug - input_value.value needs - * to point to the *address* of the krb5_principal, and the gss libraries - * to a shallow copy of the krb5_principal pointer - so we need to keep - * the krb5_principal around until we do the gss_release_name. MIT *SUCKS* ! - * Just one more way in which MIT engineers screwed me over.... JRA. - * - * That's the reason for principal not beeing a local var in this function - */ - input_name.value = &p->principal; - input_name.length = sizeof(p->principal); + input_name.value = p->string; + input_name.length = strlen(p->string); gss_rc = gss_import_name(&minor_status, &input_name, &nt_principal, &p->name); if (gss_rc) { @@ -715,7 +674,7 @@ static ADS_STATUS ads_generate_service_principal(ADS_STRUCT *ads, } #endif - return status; + return ADS_SUCCESS; } /* -- cgit From ab9d7bf4f950a78d9ca7973294d133290c99096c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 14 Sep 2007 17:42:10 +0000 Subject: r25165: Use talloc_asprintf_append_buffer with an unmodified string. Jeremy. (This used to be commit fe30a523dfc77cc373145624246fd3ad5c62b9ac) --- source3/libads/ldap_schema.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap_schema.c b/source3/libads/ldap_schema.c index 170ee65df7..ff41ccc861 100644 --- a/source3/libads/ldap_schema.c +++ b/source3/libads/ldap_schema.c @@ -48,13 +48,13 @@ ADS_STATUS ads_get_attrnames_by_oids(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, for (i=0; i Date: Wed, 26 Sep 2007 01:02:52 +0000 Subject: r25328: When using ldap sasl wrapping with gssapi it's important to receive warnings for clock-skew errors. Guenther (This used to be commit 53c99d415d605ab03e3646f6096aff794457dd33) --- source3/libads/sasl.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index c4b383e026..dec8756a86 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -811,6 +811,11 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) if (ADS_ERR_OK(status)) { status = ads_sasl_spnego_krb5_bind(ads, &p); + if (!ADS_ERR_OK(status)) { + DEBUG(0,("kinit succeeded but " + "ads_sasl_spnego_krb5_bind failed: %s\n", + ads_errstr(status))); + } } ads_free_service_principal(&p); -- cgit From 3529156971e17c7ec13f6a6243f7b613e4666cdd Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 28 Sep 2007 03:54:42 +0000 Subject: r25400: Windows 2008 (Longhorn) Interop fixes for AD specific auth2 flags, and client fixes. Patch from Todd Stetcher . (This used to be commit 8304ccba7346597425307e260e88647e49081f68) --- source3/libads/sasl.c | 4 +++- source3/libads/util.c | 54 ++++++++++++++++++++------------------------------- 2 files changed, 24 insertions(+), 34 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index dec8756a86..590052ec85 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -747,6 +747,7 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) char *OIDs[ASN1_MAX_OIDS]; #ifdef HAVE_KRB5 BOOL got_kerberos_mechanism = False; + BOOL try_kerberos = True; #endif rc = ldap_sasl_bind_s(ads->ldap.ld, NULL, "GSS-SPNEGO", NULL, NULL, NULL, &scred); @@ -784,7 +785,8 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) #endif free(OIDs[i]); } - DEBUG(3,("ads_sasl_spnego_bind: got server principal name = %s\n", given_principal)); + DEBUG(3,("ads_sasl_spnego_bind: got server principal name = %s\n", + (given_principal ? given_principal : NULL))); #ifdef HAVE_KRB5 if (!(ads->auth.flags & ADS_AUTH_DISABLE_KERBEROS) && diff --git a/source3/libads/util.c b/source3/libads/util.c index af96c3e10a..472fe4a214 100644 --- a/source3/libads/util.c +++ b/source3/libads/util.c @@ -55,57 +55,45 @@ failed: ADS_STATUS ads_guess_service_principal(ADS_STRUCT *ads, char **returned_principal) { + ADS_STATUS status; char *princ = NULL; + char *server = NULL; + char *server_realm = NULL; if (ads->server.realm && ads->server.ldap_server) { - char *server, *server_realm; - server = SMB_STRDUP(ads->server.ldap_server); server_realm = SMB_STRDUP(ads->server.realm); - if (!server || !server_realm) { - return ADS_ERROR(LDAP_NO_MEMORY); - } - - strlower_m(server); - strupper_m(server_realm); - asprintf(&princ, "ldap/%s@%s", server, server_realm); - - SAFE_FREE(server); - SAFE_FREE(server_realm); - - if (!princ) { - return ADS_ERROR(LDAP_NO_MEMORY); + if (!server || !server_realm) { + status = ADS_ERROR(LDAP_NO_MEMORY); + goto fail; } } else if (ads->config.realm && ads->config.ldap_server_name) { - char *server, *server_realm; - server = SMB_STRDUP(ads->config.ldap_server_name); server_realm = SMB_STRDUP(ads->config.realm); - if (!server || !server_realm) { - return ADS_ERROR(LDAP_NO_MEMORY); - } - - strlower_m(server); - strupper_m(server_realm); - asprintf(&princ, "ldap/%s@%s", server, server_realm); - - SAFE_FREE(server); - SAFE_FREE(server_realm); - - if (!princ) { - return ADS_ERROR(LDAP_NO_MEMORY); - } + if (!server || !server_realm) { + status = ADS_ERROR(LDAP_NO_MEMORY); + goto fail; + } } + strlower_m(server); + strupper_m(server_realm); + asprintf(&princ, "ldap/%s@%s", server, server_realm); + if (!princ) { - return ADS_ERROR(LDAP_PARAM_ERROR); + status = ADS_ERROR(LDAP_PARAM_ERROR); } *returned_principal = princ; + status = ADS_SUCCESS; + +fail: + SAFE_FREE(server); + SAFE_FREE(server_realm); - return ADS_SUCCESS; + return status; } #endif -- cgit From 5221ebb299081da6a806362212c6a8ceb9cc70a8 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 28 Sep 2007 18:15:34 +0000 Subject: r25407: Revert Longhorn join patch as it is not correct for the 3.2 tree. The translate_name() used by cli_session_setup_spnego() cann rely Winbindd since it is needed by the join process (and hence before Winbind can be run). (This used to be commit 00a93ed336c5f36643e6e33bd277608eaf05677c) --- source3/libads/sasl.c | 4 +--- source3/libads/util.c | 54 +++++++++++++++++++++++++++++++-------------------- 2 files changed, 34 insertions(+), 24 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 590052ec85..dec8756a86 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -747,7 +747,6 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) char *OIDs[ASN1_MAX_OIDS]; #ifdef HAVE_KRB5 BOOL got_kerberos_mechanism = False; - BOOL try_kerberos = True; #endif rc = ldap_sasl_bind_s(ads->ldap.ld, NULL, "GSS-SPNEGO", NULL, NULL, NULL, &scred); @@ -785,8 +784,7 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) #endif free(OIDs[i]); } - DEBUG(3,("ads_sasl_spnego_bind: got server principal name = %s\n", - (given_principal ? given_principal : NULL))); + DEBUG(3,("ads_sasl_spnego_bind: got server principal name = %s\n", given_principal)); #ifdef HAVE_KRB5 if (!(ads->auth.flags & ADS_AUTH_DISABLE_KERBEROS) && diff --git a/source3/libads/util.c b/source3/libads/util.c index 472fe4a214..af96c3e10a 100644 --- a/source3/libads/util.c +++ b/source3/libads/util.c @@ -55,45 +55,57 @@ failed: ADS_STATUS ads_guess_service_principal(ADS_STRUCT *ads, char **returned_principal) { - ADS_STATUS status; char *princ = NULL; - char *server = NULL; - char *server_realm = NULL; if (ads->server.realm && ads->server.ldap_server) { + char *server, *server_realm; + server = SMB_STRDUP(ads->server.ldap_server); server_realm = SMB_STRDUP(ads->server.realm); - if (!server || !server_realm) { - status = ADS_ERROR(LDAP_NO_MEMORY); - goto fail; + if (!server || !server_realm) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + + strlower_m(server); + strupper_m(server_realm); + asprintf(&princ, "ldap/%s@%s", server, server_realm); + + SAFE_FREE(server); + SAFE_FREE(server_realm); + + if (!princ) { + return ADS_ERROR(LDAP_NO_MEMORY); } } else if (ads->config.realm && ads->config.ldap_server_name) { + char *server, *server_realm; + server = SMB_STRDUP(ads->config.ldap_server_name); server_realm = SMB_STRDUP(ads->config.realm); - if (!server || !server_realm) { - status = ADS_ERROR(LDAP_NO_MEMORY); - goto fail; - } - } + if (!server || !server_realm) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + + strlower_m(server); + strupper_m(server_realm); + asprintf(&princ, "ldap/%s@%s", server, server_realm); - strlower_m(server); - strupper_m(server_realm); - asprintf(&princ, "ldap/%s@%s", server, server_realm); + SAFE_FREE(server); + SAFE_FREE(server_realm); + + if (!princ) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + } if (!princ) { - status = ADS_ERROR(LDAP_PARAM_ERROR); + return ADS_ERROR(LDAP_PARAM_ERROR); } *returned_principal = princ; - status = ADS_SUCCESS; - -fail: - SAFE_FREE(server); - SAFE_FREE(server_realm); - return status; + return ADS_SUCCESS; } #endif -- cgit From b12e11f29f7b6f02960c1f87cb87c0341403246c Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sat, 29 Sep 2007 06:44:39 +0000 Subject: r25422: Get rid of some cast warnings. (This used to be commit 3e155b249e03cc9f7bd0cbf3a3ab8a57536bf0ce) --- source3/libads/sasl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index dec8756a86..d5eeb8e2b3 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -268,7 +268,7 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) #ifdef HAVE_GSSAPI static ADS_STATUS ads_sasl_gssapi_wrap(ADS_STRUCT *ads, uint8 *buf, uint32 len) { - gss_ctx_id_t context_handle = ads->ldap.wrap_private_data; + gss_ctx_id_t context_handle = (gss_ctx_id_t)ads->ldap.wrap_private_data; ADS_STATUS status; int gss_rc; uint32 minor_status; @@ -309,7 +309,7 @@ static ADS_STATUS ads_sasl_gssapi_wrap(ADS_STRUCT *ads, uint8 *buf, uint32 len) static ADS_STATUS ads_sasl_gssapi_unwrap(ADS_STRUCT *ads) { - gss_ctx_id_t context_handle = ads->ldap.wrap_private_data; + gss_ctx_id_t context_handle = (gss_ctx_id_t)ads->ldap.wrap_private_data; ADS_STATUS status; int gss_rc; uint32 minor_status; @@ -347,7 +347,7 @@ static ADS_STATUS ads_sasl_gssapi_unwrap(ADS_STRUCT *ads) static void ads_sasl_gssapi_disconnect(ADS_STRUCT *ads) { - gss_ctx_id_t context_handle = ads->ldap.wrap_private_data; + gss_ctx_id_t context_handle = (gss_ctx_id_t)ads->ldap.wrap_private_data; uint32 minor_status; gss_delete_sec_context(&minor_status, &context_handle, GSS_C_NO_BUFFER); -- cgit From e5a951325a6cac8567af3a66de6d2df577508ae4 Mon Sep 17 00:00:00 2001 From: "Gerald (Jerry) Carter" Date: Wed, 10 Oct 2007 15:34:30 -0500 Subject: [GLUE] Rsync SAMBA_3_2_0 SVN r25598 in order to create the v3-2-test branch. (This used to be commit 5c6c8e1fe93f340005110a7833946191659d88ab) --- source3/libads/ads_status.c | 13 ------------- source3/libads/ldap_utils.c | 34 +++++++++++++++++----------------- 2 files changed, 17 insertions(+), 30 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_status.c b/source3/libads/ads_status.c index 742304b6fc..3f0ab57638 100644 --- a/source3/libads/ads_status.c +++ b/source3/libads/ads_status.c @@ -83,10 +83,6 @@ NTSTATUS ads_ntstatus(ADS_STATUS status) #ifdef HAVE_KRB5 case ENUM_ADS_ERROR_KRB5: return krb5_to_nt_status(status.err.rc); -#endif -#ifdef HAVE_GSSAPI - case ENUM_ADS_ERROR_GSS: - return map_nt_error_from_gss(status.err.rc, status.minor_status); #endif default: break; @@ -146,12 +142,3 @@ const char *ads_errstr(ADS_STATUS status) } } -#ifdef HAVE_GSSAPI -NTSTATUS gss_err_to_ntstatus(uint32 maj, uint32 min) -{ - ADS_STATUS adss = ADS_ERROR_GSS(maj, min); - DEBUG(10,("gss_err_to_ntstatus: Error %s\n", - ads_errstr(adss) )); - return ads_ntstatus(adss); -} -#endif diff --git a/source3/libads/ldap_utils.c b/source3/libads/ldap_utils.c index 2f5c11b90c..18f7da81d7 100644 --- a/source3/libads/ldap_utils.c +++ b/source3/libads/ldap_utils.c @@ -60,8 +60,8 @@ static ADS_STATUS ads_do_search_retry_internal(ADS_STRUCT *ads, const char *bind status = ads_do_search_all_args(ads, bp, scope, expr, attrs, args, res); } if (ADS_ERR_OK(status)) { - DEBUG(5,("Search for %s in <%s> gave %d replies\n", - expr, bp, ads_count_replies(ads, *res))); + DEBUG(5,("Search for %s in <%s> gave %d replies\n", + expr, bp, ads_count_replies(ads, *res))); SAFE_FREE(bp); return status; } @@ -159,6 +159,21 @@ static ADS_STATUS ads_do_search_retry_internal(ADS_STRUCT *ads, const char *bind "(objectclass=*)", attrs, &args, res); } + ADS_STATUS ads_search_retry_dn_sd_flags(ADS_STRUCT *ads, LDAPMessage **res, + uint32 sd_flags, + const char *dn, + const char **attrs) +{ + ads_control args; + + args.control = ADS_SD_FLAGS_OID; + args.val = sd_flags; + args.critical = True; + + return ads_do_search_retry_args(ads, dn, LDAP_SCOPE_BASE, + "(objectclass=*)", attrs, &args, res); +} + ADS_STATUS ads_search_retry_extended_dn_ranged(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char *dn, const char **attrs, @@ -181,21 +196,6 @@ static ADS_STATUS ads_do_search_retry_internal(ADS_STRUCT *ads, const char *bind "(objectclass=*)", &args, attrs[0], strings, num_strings); -} - - ADS_STATUS ads_search_retry_dn_sd_flags(ADS_STRUCT *ads, LDAPMessage **res, - uint32 sd_flags, - const char *dn, - const char **attrs) -{ - ads_control args; - - args.control = ADS_SD_FLAGS_OID; - args.val = sd_flags; - args.critical = True; - - return ads_do_search_retry_args(ads, dn, LDAP_SCOPE_BASE, - "(objectclass=*)", attrs, &args, res); } ADS_STATUS ads_search_retry_sid(ADS_STRUCT *ads, LDAPMessage **res, -- cgit From 30191d1a5704ad2b158386b511558972d539ce47 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 Oct 2007 17:40:25 -0700 Subject: RIP BOOL. Convert BOOL -> bool. I found a few interesting bugs in various places whilst doing this (places that assumed BOOL == int). I also need to fix the Samba4 pidl generation (next checkin). Jeremy. (This used to be commit f35a266b3cbb3e5fa6a86be60f34fe340a3ca71f) --- source3/libads/ads_struct.c | 2 +- source3/libads/authdata.c | 38 ++++++++++++++++++------------------ source3/libads/cldap.c | 2 +- source3/libads/dns.c | 18 ++++++++--------- source3/libads/kerberos.c | 24 +++++++++++------------ source3/libads/kerberos_keytab.c | 2 +- source3/libads/kerberos_verify.c | 14 +++++++------- source3/libads/krb5_setpw.c | 6 +++--- source3/libads/ldap.c | 42 ++++++++++++++++++++-------------------- source3/libads/ldap_printer.c | 12 ++++++------ source3/libads/ldap_utils.c | 4 ++-- source3/libads/sasl.c | 4 ++-- 12 files changed, 84 insertions(+), 84 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index aac57d41fe..041878916e 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -145,7 +145,7 @@ ADS_STRUCT *ads_init(const char *realm, void ads_destroy(ADS_STRUCT **ads) { if (ads && *ads) { - BOOL is_mine; + bool is_mine; is_mine = (*ads)->is_mine; #if HAVE_LDAP diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c index bbcd2db56a..db58cf0400 100644 --- a/source3/libads/authdata.c +++ b/source3/libads/authdata.c @@ -26,7 +26,7 @@ #ifdef HAVE_KRB5 -static BOOL pac_io_logon_name(const char *desc, PAC_LOGON_NAME *logon_name, +static bool pac_io_logon_name(const char *desc, PAC_LOGON_NAME *logon_name, prs_struct *ps, int depth) { if (NULL == logon_name) @@ -60,7 +60,7 @@ static BOOL pac_io_logon_name(const char *desc, PAC_LOGON_NAME *logon_name, } #if 0 /* Unused (handled now in net_io_user_info3()) - Guenther */ -static BOOL pac_io_krb_sids(const char *desc, KRB_SID_AND_ATTRS *sid_and_attr, +static bool pac_io_krb_sids(const char *desc, KRB_SID_AND_ATTRS *sid_and_attr, prs_struct *ps, int depth) { if (NULL == sid_and_attr) @@ -84,7 +84,7 @@ static BOOL pac_io_krb_sids(const char *desc, KRB_SID_AND_ATTRS *sid_and_attr, } -static BOOL pac_io_krb_attrs(const char *desc, KRB_SID_AND_ATTRS *sid_and_attr, +static bool pac_io_krb_attrs(const char *desc, KRB_SID_AND_ATTRS *sid_and_attr, prs_struct *ps, int depth) { if (NULL == sid_and_attr) @@ -101,7 +101,7 @@ static BOOL pac_io_krb_attrs(const char *desc, KRB_SID_AND_ATTRS *sid_and_attr, return True; } -static BOOL pac_io_krb_sid_and_attr_array(const char *desc, +static bool pac_io_krb_sid_and_attr_array(const char *desc, KRB_SID_AND_ATTR_ARRAY *array, uint32 num, prs_struct *ps, int depth) @@ -150,7 +150,7 @@ static BOOL pac_io_krb_sid_and_attr_array(const char *desc, } #endif -static BOOL pac_io_group_membership(const char *desc, +static bool pac_io_group_membership(const char *desc, GROUP_MEMBERSHIP *membership, prs_struct *ps, int depth) { @@ -169,7 +169,7 @@ static BOOL pac_io_group_membership(const char *desc, } -static BOOL pac_io_group_membership_array(const char *desc, +static bool pac_io_group_membership_array(const char *desc, GROUP_MEMBERSHIP_ARRAY *array, uint32 num, prs_struct *ps, int depth) @@ -211,7 +211,7 @@ static BOOL pac_io_group_membership_array(const char *desc, } #if 0 /* Unused, replaced using an expanded net_io_user_info3() now - Guenther */ -static BOOL pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info, +static bool pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info, prs_struct *ps, int depth) { uint32 garbage, i; @@ -395,11 +395,11 @@ static BOOL pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info, } #endif -static BOOL pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info, +static bool pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info, prs_struct *ps, int depth) { uint32 garbage; - BOOL kerb_validation_info = True; + bool kerb_validation_info = True; if (NULL == info) return False; @@ -446,7 +446,7 @@ static BOOL pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info, -static BOOL pac_io_pac_signature_data(const char *desc, +static bool pac_io_pac_signature_data(const char *desc, PAC_SIGNATURE_DATA *data, uint32 length, prs_struct *ps, int depth) { @@ -487,7 +487,7 @@ static BOOL pac_io_pac_signature_data(const char *desc, return True; } -static BOOL pac_io_pac_info_hdr_ctr(const char *desc, PAC_BUFFER *hdr, +static bool pac_io_pac_info_hdr_ctr(const char *desc, PAC_BUFFER *hdr, prs_struct *ps, int depth) { if (NULL == hdr) @@ -581,7 +581,7 @@ static BOOL pac_io_pac_info_hdr_ctr(const char *desc, PAC_BUFFER *hdr, return True; } -static BOOL pac_io_pac_info_hdr(const char *desc, PAC_BUFFER *hdr, +static bool pac_io_pac_info_hdr(const char *desc, PAC_BUFFER *hdr, prs_struct *ps, int depth) { if (NULL == hdr) @@ -604,7 +604,7 @@ static BOOL pac_io_pac_info_hdr(const char *desc, PAC_BUFFER *hdr, return True; } -static BOOL pac_io_pac_data(const char *desc, PAC_DATA *data, +static bool pac_io_pac_data(const char *desc, PAC_DATA *data, prs_struct *ps, int depth) { int i; @@ -965,8 +965,8 @@ NTSTATUS kerberos_return_pac(TALLOC_CTX *mem_ctx, time_t *expire_time, time_t *renew_till_time, const char *cache_name, - BOOL request_pac, - BOOL add_netbios_addr, + bool request_pac, + bool add_netbios_addr, time_t renewable_time, PAC_DATA **pac_ret) { @@ -1104,8 +1104,8 @@ static NTSTATUS kerberos_return_pac_logon_info(TALLOC_CTX *mem_ctx, time_t *expire_time, time_t *renew_till_time, const char *cache_name, - BOOL request_pac, - BOOL add_netbios_addr, + bool request_pac, + bool add_netbios_addr, time_t renewable_time, PAC_LOGON_INFO **logon_info) { @@ -1154,8 +1154,8 @@ NTSTATUS kerberos_return_info3_from_pac(TALLOC_CTX *mem_ctx, time_t *expire_time, time_t *renew_till_time, const char *cache_name, - BOOL request_pac, - BOOL add_netbios_addr, + bool request_pac, + bool add_netbios_addr, time_t renewable_time, NET_USER_INFO_3 **info3) { diff --git a/source3/libads/cldap.c b/source3/libads/cldap.c index de0e2e71e4..39e736f28a 100644 --- a/source3/libads/cldap.c +++ b/source3/libads/cldap.c @@ -289,7 +289,7 @@ static int recv_cldap_netlogon(int sock, struct cldap_netlogon_reply *reply) do a cldap netlogon query. Always 389/udp *******************************************************************/ -BOOL ads_cldap_netlogon(const char *server, const char *realm, struct cldap_netlogon_reply *reply) +bool ads_cldap_netlogon(const char *server, const char *realm, struct cldap_netlogon_reply *reply) { int sock; int ret; diff --git a/source3/libads/dns.c b/source3/libads/dns.c index 02baec78fb..7959e910a8 100644 --- a/source3/libads/dns.c +++ b/source3/libads/dns.c @@ -65,7 +65,7 @@ /********************************************************************* *********************************************************************/ -static BOOL ads_dns_parse_query( TALLOC_CTX *ctx, uint8 *start, uint8 *end, +static bool ads_dns_parse_query( TALLOC_CTX *ctx, uint8 *start, uint8 *end, uint8 **ptr, struct dns_query *q ) { uint8 *p = *ptr; @@ -103,7 +103,7 @@ static BOOL ads_dns_parse_query( TALLOC_CTX *ctx, uint8 *start, uint8 *end, /********************************************************************* *********************************************************************/ -static BOOL ads_dns_parse_rr( TALLOC_CTX *ctx, uint8 *start, uint8 *end, +static bool ads_dns_parse_rr( TALLOC_CTX *ctx, uint8 *start, uint8 *end, uint8 **ptr, struct dns_rr *rr ) { uint8 *p = *ptr; @@ -157,7 +157,7 @@ static BOOL ads_dns_parse_rr( TALLOC_CTX *ctx, uint8 *start, uint8 *end, /********************************************************************* *********************************************************************/ -static BOOL ads_dns_parse_rr_srv( TALLOC_CTX *ctx, uint8 *start, uint8 *end, +static bool ads_dns_parse_rr_srv( TALLOC_CTX *ctx, uint8 *start, uint8 *end, uint8 **ptr, struct dns_rr_srv *srv ) { struct dns_rr rr; @@ -202,7 +202,7 @@ static BOOL ads_dns_parse_rr_srv( TALLOC_CTX *ctx, uint8 *start, uint8 *end, /********************************************************************* *********************************************************************/ -static BOOL ads_dns_parse_rr_ns( TALLOC_CTX *ctx, uint8 *start, uint8 *end, +static bool ads_dns_parse_rr_ns( TALLOC_CTX *ctx, uint8 *start, uint8 *end, uint8 **ptr, struct dns_rr_ns *nsrec ) { struct dns_rr rr; @@ -638,10 +638,10 @@ static char *sitename_key(const char *realm) We store indefinately as every new CLDAP query will re-write this. ****************************************************************************/ -BOOL sitename_store(const char *realm, const char *sitename) +bool sitename_store(const char *realm, const char *sitename) { time_t expire; - BOOL ret = False; + bool ret = False; char *key; if (!gencache_init()) { @@ -681,7 +681,7 @@ char *sitename_fetch(const char *realm) { char *sitename = NULL; time_t timeout; - BOOL ret = False; + bool ret = False; const char *query_realm; char *key; @@ -713,9 +713,9 @@ char *sitename_fetch(const char *realm) Did the sitename change ? ****************************************************************************/ -BOOL stored_sitename_changed(const char *realm, const char *sitename) +bool stored_sitename_changed(const char *realm, const char *sitename) { - BOOL ret = False; + bool ret = False; char *new_sitename; diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 62a4f84e10..281ca2fd68 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -54,11 +54,11 @@ kerb_prompter(krb5_context ctx, void *data, return 0; } -static BOOL smb_krb5_err_io_nstatus(TALLOC_CTX *mem_ctx, +static bool smb_krb5_err_io_nstatus(TALLOC_CTX *mem_ctx, DATA_BLOB *edata_blob, KRB5_EDATA_NTSTATUS *edata) { - BOOL ret = False; + bool ret = False; prs_struct ps; if (!mem_ctx || !edata_blob || !edata) @@ -88,7 +88,7 @@ static BOOL smb_krb5_err_io_nstatus(TALLOC_CTX *mem_ctx, return ret; } - static BOOL smb_krb5_get_ntstatus_from_krb5_error(krb5_error *error, + static bool smb_krb5_get_ntstatus_from_krb5_error(krb5_error *error, NTSTATUS *nt_status) { DATA_BLOB edata; @@ -137,11 +137,11 @@ static BOOL smb_krb5_err_io_nstatus(TALLOC_CTX *mem_ctx, return True; } - static BOOL smb_krb5_get_ntstatus_from_krb5_error_init_creds_opt(krb5_context ctx, + static bool smb_krb5_get_ntstatus_from_krb5_error_init_creds_opt(krb5_context ctx, krb5_get_init_creds_opt *opt, NTSTATUS *nt_status) { - BOOL ret = False; + bool ret = False; krb5_error *error = NULL; #ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_GET_ERROR @@ -186,8 +186,8 @@ int kerberos_kinit_password_ext(const char *principal, time_t *expire_time, time_t *renew_till_time, const char *cache_name, - BOOL request_pac, - BOOL add_netbios_addr, + bool request_pac, + bool add_netbios_addr, time_t renewable_time, NTSTATUS *ntstatus) { @@ -443,10 +443,10 @@ static char* des_salt_key( void ) /************************************************************************ ************************************************************************/ -BOOL kerberos_secrets_store_des_salt( const char* salt ) +bool kerberos_secrets_store_des_salt( const char* salt ) { char* key; - BOOL ret; + bool ret; if ( (key = des_salt_key()) == NULL ) { DEBUG(0,("kerberos_secrets_store_des_salt: failed to generate key!\n")); @@ -535,12 +535,12 @@ krb5_principal kerberos_fetch_salt_princ_for_host_princ(krb5_context context, Setting principal to NULL deletes this entry. ************************************************************************/ -BOOL kerberos_secrets_store_salting_principal(const char *service, +bool kerberos_secrets_store_salting_principal(const char *service, int enctype, const char *principal) { char *key = NULL; - BOOL ret = False; + bool ret = False; krb5_context context = NULL; krb5_principal princ = NULL; char *princ_s = NULL; @@ -700,7 +700,7 @@ static char *get_kdc_ip_string(char *mem_ctx, const char *realm, const char *sit run as root or will fail (which is a good thing :-). ************************************************************************/ -BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *domain, +bool create_local_private_krb5_conf_for_domain(const char *realm, const char *domain, const char *sitename, struct in_addr ip) { char *dname = talloc_asprintf(NULL, "%s/smb_krb5", lp_lockdir()); diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c index 342e79ddd8..d0161ada01 100644 --- a/source3/libads/kerberos_keytab.c +++ b/source3/libads/kerberos_keytab.c @@ -57,7 +57,7 @@ static int smb_krb5_kt_add_entry( krb5_context context, krb5_keytab keytab, if (ret != KRB5_KT_END && ret != ENOENT ) { DEBUG(3,("smb_krb5_kt_add_entry: Will try to delete old keytab entries\n")); while(!krb5_kt_next_entry(context, keytab, &kt_entry, &cursor)) { - BOOL compare_name_ok = False; + bool compare_name_ok = False; ret = smb_krb5_unparse_name(context, kt_entry.principal, &ktprinc); if (ret) { diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 0edb5327d3..7040093e90 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -37,7 +37,7 @@ const krb5_data *krb5_princ_component(krb5_context, krb5_principal, int ); ads_keytab_add_entry function for details. ***********************************************************************************/ -static BOOL ads_keytab_verify_ticket(krb5_context context, +static bool ads_keytab_verify_ticket(krb5_context context, krb5_auth_context auth_context, const DATA_BLOB *ticket, krb5_ticket **pp_tkt, @@ -45,7 +45,7 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_error_code *perr) { krb5_error_code ret = 0; - BOOL auth_ok = False; + bool auth_ok = False; krb5_keytab keytab = NULL; krb5_kt_cursor kt_cursor; krb5_keytab_entry kt_entry; @@ -210,7 +210,7 @@ static krb5_error_code ads_secrets_verify_ticket(krb5_context context, krb5_error_code *perr) { krb5_error_code ret = 0; - BOOL auth_ok = False; + bool auth_ok = False; char *password_s = NULL; krb5_data password; krb5_enctype enctypes[] = { @@ -312,7 +312,7 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, PAC_DATA **pac_data, DATA_BLOB *ap_rep, DATA_BLOB *session_key, - BOOL use_replay_cache) + bool use_replay_cache) { NTSTATUS sret = NT_STATUS_LOGON_FAILURE; NTSTATUS pac_ret; @@ -329,9 +329,9 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, krb5_principal host_princ = NULL; krb5_const_principal client_principal = NULL; char *host_princ_s = NULL; - BOOL auth_ok = False; - BOOL got_replay_mutex = False; - BOOL got_auth_data = False; + bool auth_ok = False; + bool got_replay_mutex = False; + bool got_auth_data = False; ZERO_STRUCT(packet); ZERO_STRUCT(auth_data); diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 24220685f3..73dffe7c1b 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -136,7 +136,7 @@ static krb5_error_code build_kpasswd_request(uint16 pversion, krb5_data *ap_req, const char *princ, const char *passwd, - BOOL use_tcp, + bool use_tcp, krb5_data *packet) { krb5_error_code ret; @@ -267,7 +267,7 @@ static krb5_error_code setpw_result_code_string(krb5_context context, } } static krb5_error_code parse_setpw_reply(krb5_context context, - BOOL use_tcp, + bool use_tcp, krb5_auth_context auth_context, krb5_data *packet) { @@ -404,7 +404,7 @@ static ADS_STATUS do_krb5_kpasswd_request(krb5_context context, struct sockaddr remote_addr, local_addr; struct in_addr *addr = interpret_addr2(kdc_host); krb5_address local_kaddr, remote_kaddr; - BOOL use_tcp = False; + bool use_tcp = False; ret = krb5_mk_req_extended(context, &auth_context, AP_OPTS_USE_SUBKEY, diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index b1a86ad3d3..f85d3cd7b0 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -118,7 +118,7 @@ static int ldap_search_with_timeout(LDAP *ld, Do client and server sitename match ? **********************************************/ -BOOL ads_sitename_match(ADS_STRUCT *ads) +bool ads_sitename_match(ADS_STRUCT *ads) { if (ads->config.server_site_name == NULL && ads->config.client_site_name == NULL ) { @@ -142,7 +142,7 @@ BOOL ads_sitename_match(ADS_STRUCT *ads) Is this the closest DC ? **********************************************/ -BOOL ads_closest_dc(ADS_STRUCT *ads) +bool ads_closest_dc(ADS_STRUCT *ads) { if (ads->config.flags & ADS_CLOSEST) { DEBUG(10,("ads_closest_dc: ADS_CLOSEST flag set\n")); @@ -166,7 +166,7 @@ BOOL ads_closest_dc(ADS_STRUCT *ads) try a connection to a given ldap server, returning True and setting the servers IP in the ads struct if successful */ -BOOL ads_try_connect(ADS_STRUCT *ads, const char *server ) +bool ads_try_connect(ADS_STRUCT *ads, const char *server ) { char *srv; struct cldap_netlogon_reply cldap_reply; @@ -246,8 +246,8 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads) int count, i=0; struct ip_service *ip_list; pstring realm; - BOOL got_realm = False; - BOOL use_own_domain = False; + bool got_realm = False; + bool use_own_domain = False; char *sitename; NTSTATUS status = NT_STATUS_UNSUCCESSFUL; @@ -864,7 +864,7 @@ static ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, **/ ADS_STATUS ads_do_search_all_fn(ADS_STRUCT *ads, const char *bind_path, int scope, const char *expr, const char **attrs, - BOOL(*fn)(ADS_STRUCT *, char *, void **, void *), + bool (*fn)(ADS_STRUCT *, char *, void **, void *), void *data_area) { struct berval *cookie = NULL; @@ -1738,7 +1738,7 @@ done: **/ ADS_STATUS ads_move_machine_acct(ADS_STRUCT *ads, const char *machine_name, - const char *org_unit, BOOL *moved) + const char *org_unit, bool *moved) { ADS_STATUS rc; int ldap_status; @@ -1747,7 +1747,7 @@ ADS_STATUS ads_move_machine_acct(ADS_STRUCT *ads, const char *machine_name, char *computer_dn = NULL; char *parent_dn; char *computer_rdn = NULL; - BOOL need_move = False; + bool need_move = False; if (asprintf(&filter, "(samAccountName=%s$)", machine_name) == -1) { rc = ADS_ERROR(LDAP_NO_MEMORY); @@ -1886,11 +1886,11 @@ static void dump_string(const char *field, char **values) used for debugging */ -static BOOL ads_dump_field(ADS_STRUCT *ads, char *field, void **values, void *data_area) +static bool ads_dump_field(ADS_STRUCT *ads, char *field, void **values, void *data_area) { const struct { const char *name; - BOOL string; + bool string; void (*handler)(ADS_STRUCT *, const char *, struct berval **); } handlers[] = { {"objectGUID", False, dump_guid}, @@ -1952,7 +1952,7 @@ static BOOL ads_dump_field(ADS_STRUCT *ads, char *field, void **values, void *da * @param data_area user-defined area to pass to function **/ void ads_process_results(ADS_STRUCT *ads, LDAPMessage *res, - BOOL(*fn)(ADS_STRUCT *, char *, void **, void *), + bool (*fn)(ADS_STRUCT *, char *, void **, void *), void *data_area) { LDAPMessage *msg; @@ -1974,7 +1974,7 @@ static BOOL ads_dump_field(ADS_STRUCT *ads, char *field, void **values, void *da struct berval **ber_vals; char **str_vals, **utf8_vals; char *field; - BOOL string; + bool string; pull_utf8_talloc(ctx, &field, utf8_field); string = fn(ads, field, NULL, data_area); @@ -2126,7 +2126,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) char **current_strings, const char **next_attribute, size_t *num_strings, - BOOL *more_strings) + bool *more_strings) { char *attr; char *expected_range_attrib, *range_attr; @@ -2243,7 +2243,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) * @param v Pointer to int to store result * @return boolean inidicating success */ - BOOL ads_pull_uint32(ADS_STRUCT *ads, LDAPMessage *msg, const char *field, + bool ads_pull_uint32(ADS_STRUCT *ads, LDAPMessage *msg, const char *field, uint32 *v) { char **values; @@ -2268,7 +2268,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) * @param guid 37-byte area to receive text guid * @return boolean indicating success **/ - BOOL ads_pull_guid(ADS_STRUCT *ads, LDAPMessage *msg, struct GUID *guid) + bool ads_pull_guid(ADS_STRUCT *ads, LDAPMessage *msg, struct GUID *guid) { char **values; UUID_FLAT flat_guid; @@ -2297,11 +2297,11 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) * @param sid Pointer to sid to store result * @return boolean inidicating success */ - BOOL ads_pull_sid(ADS_STRUCT *ads, LDAPMessage *msg, const char *field, + bool ads_pull_sid(ADS_STRUCT *ads, LDAPMessage *msg, const char *field, DOM_SID *sid) { struct berval **values; - BOOL ret = False; + bool ret = False; values = ldap_get_values_len(ads->ldap.ld, msg, field); @@ -2328,7 +2328,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) LDAPMessage *msg, const char *field, DOM_SID **sids) { struct berval **values; - BOOL ret; + bool ret; int count, i; values = ldap_get_values_len(ads->ldap.ld, msg, field); @@ -2372,11 +2372,11 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) * @param sd Pointer to *SEC_DESC to store result (talloc()ed) * @return boolean inidicating success */ - BOOL ads_pull_sd(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, + bool ads_pull_sd(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, LDAPMessage *msg, const char *field, SEC_DESC **sd) { struct berval **values; - BOOL ret = False; + bool ret = False; values = ldap_get_values_len(ads->ldap.ld, msg, field); @@ -2788,7 +2788,7 @@ ADS_STATUS ads_upn_suffixes(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char ***suffix * @param sid pointer to a DOM_SID * @return boolean inidicating success **/ -BOOL ads_get_sid_from_extended_dn(TALLOC_CTX *mem_ctx, +bool ads_get_sid_from_extended_dn(TALLOC_CTX *mem_ctx, const char *extended_dn, enum ads_extended_dn_flags flags, DOM_SID *sid) diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index 0c6a280c36..05fbc071d8 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -99,7 +99,7 @@ ADS_STATUS ads_add_printer_entry(ADS_STRUCT *ads, char *prt_dn, /* map a REG_SZ to an ldap mod */ -static BOOL map_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods, +static bool map_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods, const REGISTRY_VALUE *value) { char *str_value = NULL; @@ -120,7 +120,7 @@ static BOOL map_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods, /* map a REG_DWORD to an ldap mod */ -static BOOL map_dword(TALLOC_CTX *ctx, ADS_MODLIST *mods, +static bool map_dword(TALLOC_CTX *ctx, ADS_MODLIST *mods, const REGISTRY_VALUE *value) { char *str_value = NULL; @@ -139,7 +139,7 @@ static BOOL map_dword(TALLOC_CTX *ctx, ADS_MODLIST *mods, /* map a boolean REG_BINARY to an ldap mod */ -static BOOL map_bool(TALLOC_CTX *ctx, ADS_MODLIST *mods, +static bool map_bool(TALLOC_CTX *ctx, ADS_MODLIST *mods, const REGISTRY_VALUE *value) { char *str_value; @@ -159,7 +159,7 @@ static BOOL map_bool(TALLOC_CTX *ctx, ADS_MODLIST *mods, /* map a REG_MULTI_SZ to an ldap mod */ -static BOOL map_multi_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods, +static bool map_multi_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods, const REGISTRY_VALUE *value) { char **str_values = NULL; @@ -198,7 +198,7 @@ static BOOL map_multi_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods, struct valmap_to_ads { const char *valname; - BOOL (*fn)(TALLOC_CTX *, ADS_MODLIST *, const REGISTRY_VALUE *); + bool (*fn)(TALLOC_CTX *, ADS_MODLIST *, const REGISTRY_VALUE *); }; /* @@ -347,7 +347,7 @@ WERROR get_remote_printer_publishing_data(struct rpc_pipe_client *cli, return result; } -BOOL get_local_printer_publishing_data(TALLOC_CTX *mem_ctx, +bool get_local_printer_publishing_data(TALLOC_CTX *mem_ctx, ADS_MODLIST *mods, NT_PRINTER_DATA *data) { diff --git a/source3/libads/ldap_utils.c b/source3/libads/ldap_utils.c index 18f7da81d7..871449a81a 100644 --- a/source3/libads/ldap_utils.c +++ b/source3/libads/ldap_utils.c @@ -236,7 +236,7 @@ ADS_STATUS ads_ranged_search(ADS_STRUCT *ads, uint32 first_usn; int num_retries = 0; const char **attrs; - BOOL more_values = False; + bool more_values = False; *num_strings = 0; *strings = NULL; @@ -289,7 +289,7 @@ ADS_STATUS ads_ranged_search_internal(ADS_STRUCT *ads, size_t *num_strings, uint32 *first_usn, int *num_retries, - BOOL *more_values) + bool *more_values) { LDAPMessage *res = NULL; ADS_STATUS status; diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index d5eeb8e2b3..3b3838e390 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -369,7 +369,7 @@ static const struct ads_saslwrap_ops ads_sasl_gssapi_ops = { static ADS_STATUS ads_sasl_spnego_gsskrb5_bind(ADS_STRUCT *ads, const gss_name_t serv_name) { ADS_STATUS status; - BOOL ok; + bool ok; uint32 minor_status; int gss_rc, rc; gss_OID_desc krb5_mech_type = @@ -746,7 +746,7 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) char *given_principal = NULL; char *OIDs[ASN1_MAX_OIDS]; #ifdef HAVE_KRB5 - BOOL got_kerberos_mechanism = False; + bool got_kerberos_mechanism = False; #endif rc = ldap_sasl_bind_s(ads->ldap.ld, NULL, "GSS-SPNEGO", NULL, NULL, NULL, &scred); -- cgit From f88b7a076be74a29a3bf876b4e2705f4a1ecf42b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 24 Oct 2007 14:16:54 -0700 Subject: This is a large patch (sorry). Migrate from struct in_addr to struct sockaddr_storage in most places that matter (ie. not the nmbd and NetBIOS lookups). This passes make test on an IPv4 box, but I'll have to do more work/testing on IPv6 enabled boxes. This should now give us a framework for testing and finishing the IPv6 migration. It's at the state where someone with a working IPv6 setup should (theorecically) be able to type : smbclient //ipv6-address/share and have it work. Jeremy. (This used to be commit 98e154c3125d5732c37a72d74b0eb5cd7b6155fd) --- source3/libads/kerberos.c | 38 +++++++++++++++++++++++++------------- source3/libads/krb5_setpw.c | 28 +++++++++++++++++++++------- source3/libads/ldap.c | 35 +++++++++++++++++++++++------------ 3 files changed, 69 insertions(+), 32 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 281ca2fd68..f259c21bdb 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -614,7 +614,10 @@ int kerberos_kinit_password(const char *principal, Does DNS queries. ************************************************************************/ -static char *get_kdc_ip_string(char *mem_ctx, const char *realm, const char *sitename, struct in_addr primary_ip) +static char *get_kdc_ip_string(char *mem_ctx, + const char *realm, + const char *sitename, + struct sockaddr_storage *pss) { int i; struct ip_service *ip_srv_site = NULL; @@ -622,7 +625,8 @@ static char *get_kdc_ip_string(char *mem_ctx, const char *realm, const char *sit int count_site = 0; int count_nonsite; char *kdc_str = talloc_asprintf(mem_ctx, "\tkdc = %s\n", - inet_ntoa(primary_ip)); + print_canonical_sockaddr(mem_ctx, + pss)); if (kdc_str == NULL) { return NULL; @@ -635,12 +639,15 @@ static char *get_kdc_ip_string(char *mem_ctx, const char *realm, const char *sit get_kdc_list(realm, sitename, &ip_srv_site, &count_site); for (i = 0; i < count_site; i++) { - if (ip_equal(ip_srv_site[i].ip, primary_ip)) { + if (addr_equal(&ip_srv_site[i].ss, pss)) { continue; } - /* Append to the string - inefficient but not done often. */ + /* Append to the string - inefficient + * but not done often. */ kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n", - kdc_str, inet_ntoa(ip_srv_site[i].ip)); + kdc_str, + print_canonical_sockaddr(mem_ctx, + &ip_srv_site[i].ss)); if (!kdc_str) { SAFE_FREE(ip_srv_site); return NULL; @@ -655,13 +662,14 @@ static char *get_kdc_ip_string(char *mem_ctx, const char *realm, const char *sit for (i = 0; i < count_nonsite; i++) { int j; - if (ip_equal(ip_srv_nonsite[i].ip, primary_ip)) { + if (addr_equal(&ip_srv_nonsite[i].ss, pss)) { continue; } /* Ensure this isn't an IP already seen (YUK! this is n*n....) */ for (j = 0; j < count_site; j++) { - if (ip_equal(ip_srv_nonsite[i].ip, ip_srv_site[j].ip)) { + if (addr_equal(&ip_srv_nonsite[i].ss, + &ip_srv_site[j].ss)) { break; } /* As the lists are sorted we can break early if nonsite > site. */ @@ -675,7 +683,9 @@ static char *get_kdc_ip_string(char *mem_ctx, const char *realm, const char *sit /* Append to the string - inefficient but not done often. */ kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n", - kdc_str, inet_ntoa(ip_srv_nonsite[i].ip)); + kdc_str, + print_canonical_sockaddr(mem_ctx, + &ip_srv_nonsite[i].ss)); if (!kdc_str) { SAFE_FREE(ip_srv_site); SAFE_FREE(ip_srv_nonsite); @@ -700,8 +710,10 @@ static char *get_kdc_ip_string(char *mem_ctx, const char *realm, const char *sit run as root or will fail (which is a good thing :-). ************************************************************************/ -bool create_local_private_krb5_conf_for_domain(const char *realm, const char *domain, - const char *sitename, struct in_addr ip) +bool create_local_private_krb5_conf_for_domain(const char *realm, + const char *domain, + const char *sitename, + struct sockaddr_storage *pss) { char *dname = talloc_asprintf(NULL, "%s/smb_krb5", lp_lockdir()); char *tmpname = NULL; @@ -742,12 +754,12 @@ bool create_local_private_krb5_conf_for_domain(const char *realm, const char *do realm_upper = talloc_strdup(fname, realm); strupper_m(realm_upper); - kdc_ip_string = get_kdc_ip_string(dname, realm, sitename, ip); + kdc_ip_string = get_kdc_ip_string(dname, realm, sitename, pss); if (!kdc_ip_string) { TALLOC_FREE(dname); return False; } - + file_contents = talloc_asprintf(fname, "[libdefaults]\n\tdefault_realm = %s\n\n" "[realms]\n\t%s = {\n" "\t%s\t}\n", @@ -806,7 +818,7 @@ bool create_local_private_krb5_conf_for_domain(const char *realm, const char *do DEBUG(5,("create_local_private_krb5_conf_for_domain: wrote " "file %s with realm %s KDC = %s\n", - fname, realm_upper, inet_ntoa(ip) )); + fname, realm_upper, print_canonical_sockaddr(dname, pss) )); /* Set the environment variable to this file. */ setenv("KRB5_CONFIG", fname, 1); diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 73dffe7c1b..831a448847 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -402,11 +402,14 @@ static ADS_STATUS do_krb5_kpasswd_request(krb5_context context, int ret, sock; socklen_t addr_len; struct sockaddr remote_addr, local_addr; - struct in_addr *addr = interpret_addr2(kdc_host); + struct sockaddr_storage addr; krb5_address local_kaddr, remote_kaddr; bool use_tcp = False; + if (!interpret_string_addr(&addr, kdc_host, 0)) { + } + ret = krb5_mk_req_extended(context, &auth_context, AP_OPTS_USE_SUBKEY, NULL, credsp, &ap_req); if (ret) { @@ -422,7 +425,7 @@ static ADS_STATUS do_krb5_kpasswd_request(krb5_context context, } else { - sock = open_socket_out(SOCK_STREAM, addr, DEFAULT_KPASSWD_PORT, + sock = open_socket_out(SOCK_STREAM, &addr, DEFAULT_KPASSWD_PORT, LONG_CONNECT_TIMEOUT); } @@ -430,18 +433,29 @@ static ADS_STATUS do_krb5_kpasswd_request(krb5_context context, int rc = errno; SAFE_FREE(ap_req.data); krb5_auth_con_free(context, auth_context); - DEBUG(1,("failed to open kpasswd socket to %s (%s)\n", + DEBUG(1,("failed to open kpasswd socket to %s (%s)\n", kdc_host, strerror(errno))); return ADS_ERROR_SYSTEM(rc); } - addr_len = sizeof(remote_addr); getpeername(sock, &remote_addr, &addr_len); addr_len = sizeof(local_addr); getsockname(sock, &local_addr, &addr_len); - - setup_kaddr(&remote_kaddr, &remote_addr); - setup_kaddr(&local_kaddr, &local_addr); + + /* FIXME ! How do we do IPv6 here ? JRA. */ + if (remote_addr.sa_family != AF_INET || + local_addr.sa_family != AF_INET) { + DEBUG(1,("do_krb5_kpasswd_request: " + "no IPv6 support (yet).\n")); + close(sock); + SAFE_FREE(ap_req.data); + krb5_auth_con_free(context, auth_context); + errno = EINVAL; + return ADS_ERROR_SYSTEM(EINVAL); + } + + setup_kaddr_v4(&remote_kaddr, &remote_addr); + setup_kaddr_v4(&local_kaddr, &local_addr); ret = krb5_auth_con_setaddrs(context, auth_context, &local_kaddr, NULL); if (ret) { diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index f85d3cd7b0..0294c4a5b5 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -221,13 +221,19 @@ bool ads_try_connect(ADS_STRUCT *ads, const char *server ) ads->config.client_site_name = SMB_STRDUP(cldap_reply.client_site_name); } - ads->server.workgroup = SMB_STRDUP(cldap_reply.netbios_domain); ads->ldap.port = LDAP_PORT; - ads->ldap.ip = *interpret_addr2(srv); + if (!interpret_string_addr(&ads->ldap.ss, srv, 0)) { + DEBUG(1,("ads_try_connect: unable to convert %s " + "to an address\n", + srv)); + SAFE_FREE( srv ); + return False; + } + SAFE_FREE(srv); - + /* Store our site name. */ sitename_store( cldap_reply.domain, cldap_reply.client_site_name ); @@ -306,10 +312,10 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads) /* if we fail this loop, then giveup since all the IP addresses returned were dead */ for ( i=0; ildap); ads->ldap.last_attempt = time(NULL); @@ -378,7 +385,7 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) /* try with a user specified server */ - if (ads->server.ldap_server && + if (ads->server.ldap_server && ads_try_connect(ads, ads->server.ldap_server)) { goto got_connection; } @@ -391,7 +398,9 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) return ADS_ERROR_NT(ntstatus); got_connection: - DEBUG(3,("Connected to LDAP server %s\n", inet_ntoa(ads->ldap.ip))); + + print_sockaddr(addr, sizeof(addr), &ads->ldap.ss); + DEBUG(3,("Connected to LDAP server %s\n", addr)); if (!ads->auth.user_name) { /* Must use the userPrincipalName value here or sAMAccountName @@ -405,7 +414,8 @@ got_connection: } if (!ads->auth.kdc_server) { - ads->auth.kdc_server = SMB_STRDUP(inet_ntoa(ads->ldap.ip)); + print_sockaddr(addr, sizeof(addr), &ads->ldap.ss); + ads->auth.kdc_server = SMB_STRDUP(addr); } #if KRB5_DNS_HACK @@ -440,8 +450,9 @@ got_connection: /* cache the successful connection for workgroup and realm */ if (ads_closest_dc(ads)) { - saf_store( ads->server.workgroup, inet_ntoa(ads->ldap.ip)); - saf_store( ads->server.realm, inet_ntoa(ads->ldap.ip)); + print_sockaddr(addr, sizeof(addr), &ads->ldap.ss); + saf_store( ads->server.workgroup, addr); + saf_store( ads->server.realm, addr); } ldap_set_option(ads->ldap.ld, LDAP_OPT_PROTOCOL_VERSION, &version); -- cgit From e2d0526c9799a75f87bbbe24f2e5a268df89fea9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 29 Oct 2007 13:34:00 -0700 Subject: Change our DNS code to cope with AAAA records. A6 records look like a nightmare to use, so ignore them for now. Jeremy. (This used to be commit 814daded90781dc5a5bdd522ea8cfe5d47e6d7a7) --- source3/libads/dns.c | 294 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 189 insertions(+), 105 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/dns.c b/source3/libads/dns.c index 7959e910a8..8aca5b083e 100644 --- a/source3/libads/dns.c +++ b/source3/libads/dns.c @@ -1,18 +1,19 @@ -/* +/* Unix SMB/CIFS implementation. DNS utility library Copyright (C) Gerald (Jerry) Carter 2006. + Copyright (C) Jeremy Allison 2007. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -44,6 +45,13 @@ #if !defined(T_A) /* AIX 5.3 already defines T_A */ # define T_A ns_t_a #endif + +#if defined(HAVE_IPV6) +#if !defined(T_AAAA) +# define T_AAAA ns_t_aaaa +#endif +#endif + # define T_SRV ns_t_srv #if !defined(T_NS) /* AIX 5.3 already defines T_NS */ # define T_NS ns_t_ns @@ -73,7 +81,7 @@ static bool ads_dns_parse_query( TALLOC_CTX *ctx, uint8 *start, uint8 *end, int namelen; ZERO_STRUCTP( q ); - + if ( !start || !end || !q || !*ptr) return False; @@ -134,7 +142,7 @@ static bool ads_dns_parse_rr( TALLOC_CTX *ctx, uint8 *start, uint8 *end, rr->in_class = RSVAL(p, 2); rr->ttl = RIVAL(p, 4); rr->rdatalen = RSVAL(p, 8); - + p += 10; /* sanity check the available space */ @@ -168,7 +176,7 @@ static bool ads_dns_parse_rr_srv( TALLOC_CTX *ctx, uint8 *start, uint8 *end, if ( !start || !end || !srv || !*ptr) return -1; - /* Parse the RR entry. Coming out of the this, ptr is at the beginning + /* Parse the RR entry. Coming out of the this, ptr is at the beginning of the next record */ if ( !ads_dns_parse_rr( ctx, start, end, ptr, &rr ) ) { @@ -177,7 +185,8 @@ static bool ads_dns_parse_rr_srv( TALLOC_CTX *ctx, uint8 *start, uint8 *end, } if ( rr.type != T_SRV ) { - DEBUG(1,("ads_dns_parse_rr_srv: Bad answer type (%d)\n", rr.type)); + DEBUG(1,("ads_dns_parse_rr_srv: Bad answer type (%d)\n", + rr.type)); return False; } @@ -213,7 +222,7 @@ static bool ads_dns_parse_rr_ns( TALLOC_CTX *ctx, uint8 *start, uint8 *end, if ( !start || !end || !nsrec || !*ptr) return -1; - /* Parse the RR entry. Coming out of the this, ptr is at the beginning + /* Parse the RR entry. Coming out of the this, ptr is at the beginning of the next record */ if ( !ads_dns_parse_rr( ctx, start, end, ptr, &rr ) ) { @@ -222,14 +231,15 @@ static bool ads_dns_parse_rr_ns( TALLOC_CTX *ctx, uint8 *start, uint8 *end, } if ( rr.type != T_NS ) { - DEBUG(1,("ads_dns_parse_rr_ns: Bad answer type (%d)\n", rr.type)); + DEBUG(1,("ads_dns_parse_rr_ns: Bad answer type (%d)\n", + rr.type)); return False; } p = rr.rdata; /* ame server hostname */ - + namelen = dn_expand( start, end, p, nsname, sizeof(nsname) ); if ( namelen < 0 ) { DEBUG(1,("ads_dns_parse_rr_ns: Failed to uncompress name!\n")); @@ -249,16 +259,16 @@ static int dnssrvcmp( struct dns_rr_srv *a, struct dns_rr_srv *b ) if ( a->priority == b->priority ) { /* randomize entries with an equal weight and priority */ - if ( a->weight == b->weight ) + if ( a->weight == b->weight ) return 0; - /* higher weights should be sorted lower */ + /* higher weights should be sorted lower */ if ( a->weight > b->weight ) return -1; else return 1; } - + if ( a->priority < b->priority ) return -1; @@ -271,14 +281,14 @@ static int dnssrvcmp( struct dns_rr_srv *a, struct dns_rr_srv *b ) #define DNS_FAILED_WAITTIME 30 -static NTSTATUS dns_send_req( TALLOC_CTX *ctx, const char *name, int q_type, +static NTSTATUS dns_send_req( TALLOC_CTX *ctx, const char *name, int q_type, uint8 **buf, int *resp_length ) { uint8 *buffer = NULL; size_t buf_len; - int resp_len = NS_PACKETSZ; + int resp_len = NS_PACKETSZ; static time_t last_dns_check = 0; - static NTSTATUS last_dns_status = NT_STATUS_OK; + static NTSTATUS last_dns_status = NT_STATUS_OK; time_t now = time(NULL); /* Try to prevent bursts of DNS lookups if the server is down */ @@ -288,13 +298,13 @@ static NTSTATUS dns_send_req( TALLOC_CTX *ctx, const char *name, int q_type, if ( last_dns_check > now ) last_dns_check = 0; - /* IF we had a DNS timeout or a bad server and we are still - in the 30 second cache window, just return the previous + /* IF we had a DNS timeout or a bad server and we are still + in the 30 second cache window, just return the previous status and save the network timeout. */ if ( (NT_STATUS_EQUAL(last_dns_status,NT_STATUS_IO_TIMEOUT) || NT_STATUS_EQUAL(last_dns_status,NT_STATUS_CONNECTION_REFUSED)) && - (last_dns_check+DNS_FAILED_WAITTIME) > now ) + (last_dns_check+DNS_FAILED_WAITTIME) > now ) { DEBUG(10,("last_dns_check: Returning cached status (%s)\n", nt_errstr(last_dns_status) )); @@ -305,39 +315,44 @@ static NTSTATUS dns_send_req( TALLOC_CTX *ctx, const char *name, int q_type, do { if ( buffer ) TALLOC_FREE( buffer ); - + buf_len = resp_len * sizeof(uint8); - if (buf_len) { - if ( (buffer = TALLOC_ARRAY(ctx, uint8, buf_len)) == NULL ) { - DEBUG(0,("ads_dns_lookup_srv: talloc() failed!\n")); + if (buf_len) { + if ((buffer = TALLOC_ARRAY(ctx, uint8, buf_len)) + == NULL ) { + DEBUG(0,("ads_dns_lookup_srv: " + "talloc() failed!\n")); last_dns_status = NT_STATUS_NO_MEMORY; last_dns_check = time(NULL); - return last_dns_status; + return last_dns_status; } } - if ( (resp_len = res_query(name, C_IN, q_type, buffer, buf_len)) < 0 ) { - DEBUG(3,("ads_dns_lookup_srv: Failed to resolve %s (%s)\n", name, strerror(errno))); + if ((resp_len = res_query(name, C_IN, q_type, buffer, buf_len)) + < 0 ) { + DEBUG(3,("ads_dns_lookup_srv: " + "Failed to resolve %s (%s)\n", + name, strerror(errno))); TALLOC_FREE( buffer ); last_dns_status = NT_STATUS_UNSUCCESSFUL; - + if (errno == ETIMEDOUT) { - last_dns_status = NT_STATUS_IO_TIMEOUT; + last_dns_status = NT_STATUS_IO_TIMEOUT; } if (errno == ECONNREFUSED) { - last_dns_status = NT_STATUS_CONNECTION_REFUSED; + last_dns_status = NT_STATUS_CONNECTION_REFUSED; } last_dns_check = time(NULL); return last_dns_status; } } while ( buf_len < resp_len && resp_len < MAX_DNS_PACKET_SIZE ); - + *buf = buffer; *resp_length = resp_len; last_dns_check = time(NULL); - last_dns_status = NT_STATUS_OK; + last_dns_status = NT_STATUS_OK; return last_dns_status; } @@ -345,7 +360,10 @@ static NTSTATUS dns_send_req( TALLOC_CTX *ctx, const char *name, int q_type, Simple wrapper for a DNS SRV query *********************************************************************/ -static NTSTATUS ads_dns_lookup_srv( TALLOC_CTX *ctx, const char *name, struct dns_rr_srv **dclist, int *numdcs ) +static NTSTATUS ads_dns_lookup_srv( TALLOC_CTX *ctx, + const char *name, + struct dns_rr_srv **dclist, + int *numdcs) { uint8 *buffer = NULL; int resp_len = 0; @@ -359,8 +377,8 @@ static NTSTATUS ads_dns_lookup_srv( TALLOC_CTX *ctx, const char *name, struct dn if ( !ctx || !name || !dclist ) { return NT_STATUS_INVALID_PARAMETER; } - - /* Send the request. May have to loop several times in case + + /* Send the request. May have to loop several times in case of large replies */ status = dns_send_req( ctx, name, T_SRV, &buffer, &resp_len ); @@ -375,19 +393,23 @@ static NTSTATUS ads_dns_lookup_srv( TALLOC_CTX *ctx, const char *name, struct dn available in libresolv.a, and not the shared lib. Who knows why.... So we have to parse the DNS reply ourselves */ - /* Pull the answer RR's count from the header. Use the NMB ordering macros */ + /* Pull the answer RR's count from the header. + * Use the NMB ordering macros */ query_count = RSVAL( p, 4 ); answer_count = RSVAL( p, 6 ); auth_count = RSVAL( p, 8 ); additional_count = RSVAL( p, 10 ); - DEBUG(4,("ads_dns_lookup_srv: %d records returned in the answer section.\n", + DEBUG(4,("ads_dns_lookup_srv: " + "%d records returned in the answer section.\n", answer_count)); - + if (answer_count) { - if ( (dcs = TALLOC_ZERO_ARRAY(ctx, struct dns_rr_srv, answer_count)) == NULL ) { - DEBUG(0,("ads_dns_lookup_srv: talloc() failure for %d char*'s\n", + if ((dcs = TALLOC_ZERO_ARRAY(ctx, struct dns_rr_srv, + answer_count)) == NULL ) { + DEBUG(0,("ads_dns_lookup_srv: " + "talloc() failure for %d char*'s\n", answer_count)); return NT_STATUS_NO_MEMORY; } @@ -404,8 +426,10 @@ static NTSTATUS ads_dns_lookup_srv( TALLOC_CTX *ctx, const char *name, struct dn for ( rrnum=0; rrnum Date: Mon, 29 Oct 2007 15:03:36 -0700 Subject: Fix the setup_kaddr() call to cope with IPv6. This is the last obvious change I can see. At this point we can start claiming IPv6 support (Hurrah !:-). Jeremy. (This used to be commit bda8c0bf571c994b524a9d67eebc422033d17094) --- source3/libads/krb5_setpw.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 831a448847..852251a476 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -401,7 +401,7 @@ static ADS_STATUS do_krb5_kpasswd_request(krb5_context context, krb5_data ap_req, chpw_req, chpw_rep; int ret, sock; socklen_t addr_len; - struct sockaddr remote_addr, local_addr; + struct sockaddr_storage remote_addr, local_addr; struct sockaddr_storage addr; krb5_address local_kaddr, remote_kaddr; bool use_tcp = False; @@ -438,15 +438,14 @@ static ADS_STATUS do_krb5_kpasswd_request(krb5_context context, return ADS_ERROR_SYSTEM(rc); } addr_len = sizeof(remote_addr); - getpeername(sock, &remote_addr, &addr_len); + getpeername(sock, (struct sockaddr *)&remote_addr, &addr_len); addr_len = sizeof(local_addr); - getsockname(sock, &local_addr, &addr_len); + getsockname(sock, (struct sockaddr *)&local_addr, &addr_len); - /* FIXME ! How do we do IPv6 here ? JRA. */ - if (remote_addr.sa_family != AF_INET || - local_addr.sa_family != AF_INET) { + if (!setup_kaddr(&remote_kaddr, &remote_addr) || + !setup_kaddr(&local_kaddr, &local_addr)) { DEBUG(1,("do_krb5_kpasswd_request: " - "no IPv6 support (yet).\n")); + "Failed to setup addresses.\n")); close(sock); SAFE_FREE(ap_req.data); krb5_auth_con_free(context, auth_context); @@ -454,9 +453,6 @@ static ADS_STATUS do_krb5_kpasswd_request(krb5_context context, return ADS_ERROR_SYSTEM(EINVAL); } - setup_kaddr_v4(&remote_kaddr, &remote_addr); - setup_kaddr_v4(&local_kaddr, &local_addr); - ret = krb5_auth_con_setaddrs(context, auth_context, &local_kaddr, NULL); if (ret) { close(sock); @@ -465,7 +461,7 @@ static ADS_STATUS do_krb5_kpasswd_request(krb5_context context, DEBUG(1,("krb5_auth_con_setaddrs failed (%s)\n", error_message(ret))); return ADS_ERROR_KRB5(ret); } - + ret = build_kpasswd_request(pversion, context, auth_context, &ap_req, princ, newpw, use_tcp, &chpw_req); if (ret) { -- cgit From acb829ecc3b9af3f141425ecac032a7c722a1815 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 15 Nov 2007 18:27:26 -0800 Subject: Add MAX_DNS_NAME_LENGTH, remove more pstrings. Jeremy. (This used to be commit a1725f4ff7ed375808c78ac661b539557748d0a5) --- source3/libads/dns.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/dns.c b/source3/libads/dns.c index 8aca5b083e..cdc4b448cf 100644 --- a/source3/libads/dns.c +++ b/source3/libads/dns.c @@ -77,7 +77,7 @@ static bool ads_dns_parse_query( TALLOC_CTX *ctx, uint8 *start, uint8 *end, uint8 **ptr, struct dns_query *q ) { uint8 *p = *ptr; - pstring hostname; + char hostname[MAX_DNS_NAME_LENGTH]; int namelen; ZERO_STRUCTP( q ); @@ -115,7 +115,7 @@ static bool ads_dns_parse_rr( TALLOC_CTX *ctx, uint8 *start, uint8 *end, uint8 **ptr, struct dns_rr *rr ) { uint8 *p = *ptr; - pstring hostname; + char hostname[MAX_DNS_NAME_LENGTH]; int namelen; if ( !start || !end || !rr || !*ptr) @@ -170,7 +170,7 @@ static bool ads_dns_parse_rr_srv( TALLOC_CTX *ctx, uint8 *start, uint8 *end, { struct dns_rr rr; uint8 *p; - pstring dcname; + char dcname[MAX_DNS_NAME_LENGTH]; int namelen; if ( !start || !end || !srv || !*ptr) @@ -216,7 +216,7 @@ static bool ads_dns_parse_rr_ns( TALLOC_CTX *ctx, uint8 *start, uint8 *end, { struct dns_rr rr; uint8 *p; - pstring nsname; + char nsname[MAX_DNS_NAME_LENGTH]; int namelen; if ( !start || !end || !nsrec || !*ptr) -- cgit From de51d3dd5f673019325abba88b100b279169a1c8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 20 Nov 2007 18:55:36 -0800 Subject: More pstring removal.... Jeremy. (This used to be commit 809f5ab4c595740b28425e1667e395a6058b76a8) --- source3/libads/kerberos.c | 18 +++++++++--------- source3/libads/ldap.c | 26 +++++++++++++------------- 2 files changed, 22 insertions(+), 22 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index f259c21bdb..29e5661d3c 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -829,13 +829,15 @@ bool create_local_private_krb5_conf_for_domain(const char *realm, /* Insanity, sheer insanity..... */ if (strequal(realm, lp_realm())) { - pstring linkpath; + char linkpath[PATH_MAX+1]; int lret; lret = readlink(SYSTEM_KRB5_CONF_PATH, linkpath, sizeof(linkpath)-1); - linkpath[sizeof(pstring)-1] = '\0'; + if (lret != -1) { + linkpath[lret] = '\0'; + } - if (lret == 0 || strcmp(linkpath, fname) == 0) { + if (lret != -1 || strcmp(linkpath, fname) == 0) { /* Symlink already exists. */ TALLOC_FREE(dname); return True; @@ -843,6 +845,7 @@ bool create_local_private_krb5_conf_for_domain(const char *realm, /* Try and replace with a symlink. */ if (symlink(fname, SYSTEM_KRB5_CONF_PATH) == -1) { + const char *newpath = SYSTEM_KRB5_CONF_PATH ## ".saved"; if (errno != EEXIST) { DEBUG(0,("create_local_private_krb5_conf_for_domain: symlink " "of %s to %s failed. Errno %s\n", @@ -851,20 +854,17 @@ bool create_local_private_krb5_conf_for_domain(const char *realm, return True; /* Not a fatal error. */ } - pstrcpy(linkpath, SYSTEM_KRB5_CONF_PATH); - pstrcat(linkpath, ".saved"); - /* Yes, this is a race conditon... too bad. */ - if (rename(SYSTEM_KRB5_CONF_PATH, linkpath) == -1) { + if (rename(SYSTEM_KRB5_CONF_PATH, newpath) == -1) { DEBUG(0,("create_local_private_krb5_conf_for_domain: rename " "of %s to %s failed. Errno %s\n", - SYSTEM_KRB5_CONF_PATH, linkpath, + SYSTEM_KRB5_CONF_PATH, newpath, strerror(errno) )); TALLOC_FREE(dname); return True; /* Not a fatal error. */ } - if (symlink(fname, "/etc/krb5.conf") == -1) { + if (symlink(fname, SYSTEM_KRB5_CONF_PATH) == -1) { DEBUG(0,("create_local_private_krb5_conf_for_domain: " "forced symlink of %s to /etc/krb5.conf failed. Errno %s\n", fname, strerror(errno) )); diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 0294c4a5b5..01f6b00c02 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -251,7 +251,7 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads) const char *c_realm; int count, i=0; struct ip_service *ip_list; - pstring realm; + const char *realm; bool got_realm = False; bool use_own_domain = False; char *sitename; @@ -261,7 +261,7 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads) /* realm */ c_realm = ads->server.realm; - + if ( !c_realm || !*c_realm ) { /* special case where no realm and no workgroup means our own */ if ( !ads->server.workgroup || !*ads->server.workgroup ) { @@ -269,33 +269,33 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads) c_realm = lp_realm(); } } - - if (c_realm && *c_realm) + + if (c_realm && *c_realm) got_realm = True; - - /* we need to try once with the realm name and fallback to the + + /* we need to try once with the realm name and fallback to the netbios domain name if we fail (if netbios has not been disabled */ - + if ( !got_realm && !lp_disable_netbios() ) { c_realm = ads->server.workgroup; if (!c_realm || !*c_realm) { if ( use_own_domain ) c_realm = lp_workgroup(); } - + if ( !c_realm || !*c_realm ) { DEBUG(0,("ads_find_dc: no realm or workgroup! Don't know what to do\n")); return NT_STATUS_INVALID_PARAMETER; /* rather need MISSING_PARAMETER ... */ } } - - pstrcpy( realm, c_realm ); + + realm = c_realm; sitename = sitename_fetch(realm); again: - DEBUG(6,("ads_find_dc: looking for %s '%s'\n", + DEBUG(6,("ads_find_dc: looking for %s '%s'\n", (got_realm ? "realm" : "domain"), realm)); status = get_sorted_dc_list(realm, sitename, &ip_list, &count, got_realm); @@ -305,7 +305,7 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads) got_realm = False; goto again; } - + SAFE_FREE(sitename); return status; } @@ -338,7 +338,7 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads) continue; } } - + if ( ads_try_connect(ads, server) ) { SAFE_FREE(ip_list); SAFE_FREE(sitename); -- cgit From d5b2325fcd597813b081d17161d26d85110c100b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 24 Nov 2007 17:27:19 +0100 Subject: Remove a global (This used to be commit 3088bc76f1ceffecaa5aea039be79973c9876f0c) --- source3/libads/ads_status.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_status.c b/source3/libads/ads_status.c index 3f0ab57638..ecef9d224b 100644 --- a/source3/libads/ads_status.c +++ b/source3/libads/ads_status.c @@ -99,10 +99,6 @@ NTSTATUS ads_ntstatus(ADS_STATUS status) */ const char *ads_errstr(ADS_STATUS status) { - static char *ret; - - SAFE_FREE(ret); - switch (status.error_type) { case ENUM_ADS_ERROR_SYSTEM: return strerror(status.err.rc); @@ -117,6 +113,7 @@ const char *ads_errstr(ADS_STATUS status) #ifdef HAVE_GSSAPI case ENUM_ADS_ERROR_GSS: { + char *ret; uint32 msg_ctx; uint32 minor; gss_buffer_desc msg1, msg2; @@ -129,7 +126,9 @@ const char *ads_errstr(ADS_STATUS status) GSS_C_NULL_OID, &msg_ctx, &msg1); gss_display_status(&minor, status.minor_status, GSS_C_MECH_CODE, GSS_C_NULL_OID, &msg_ctx, &msg2); - asprintf(&ret, "%s : %s", (char *)msg1.value, (char *)msg2.value); + ret = talloc_asprintf(talloc_tos(), "%s : %s", + (char *)msg1.value, (char *)msg2.value); + SMB_ASSERT(ret != NULL); gss_release_buffer(&minor, &msg1); gss_release_buffer(&minor, &msg2); return ret; -- cgit From 1011b32678c7b32472a909b9f515698947d2a389 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 25 Nov 2007 10:10:52 +0100 Subject: Remove some statics (This used to be commit 1fab16ffb888cd4ec18e52d9da33976a67a5d104) --- source3/libads/disp_sec.c | 4 ++-- source3/libads/ldap.c | 11 +++++++---- 2 files changed, 9 insertions(+), 6 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/disp_sec.c b/source3/libads/disp_sec.c index e85809635f..e211ef69e4 100644 --- a/source3/libads/disp_sec.c +++ b/source3/libads/disp_sec.c @@ -114,14 +114,14 @@ static void ads_disp_sec_ace_object(ADS_STRUCT *ads, { if (object->flags & SEC_ACE_OBJECT_PRESENT) { printf("Object type: SEC_ACE_OBJECT_PRESENT\n"); - printf("Object GUID: %s (%s)\n", smb_uuid_string_static( + printf("Object GUID: %s (%s)\n", smb_uuid_string(mem_ctx, object->type.type), ads_interprete_guid_from_object(ads, mem_ctx, &object->type.type)); } if (object->flags & SEC_ACE_OBJECT_INHERITED_PRESENT) { printf("Object type: SEC_ACE_OBJECT_INHERITED_PRESENT\n"); - printf("Object GUID: %s (%s)\n", smb_uuid_string_static( + printf("Object GUID: %s (%s)\n", smb_uuid_string(mem_ctx, object->inherited_type.inherited_type), ads_interprete_guid_from_object(ads, mem_ctx, &object->inherited_type.inherited_type)); diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 01f6b00c02..533aa3026f 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1828,11 +1828,14 @@ static void dump_binary(ADS_STRUCT *ads, const char *field, struct berval **valu static void dump_guid(ADS_STRUCT *ads, const char *field, struct berval **values) { int i; - UUID_FLAT guid; for (i=0; values[i]; i++) { + + UUID_FLAT guid; + struct GUID tmp; + memcpy(guid.info, values[i]->bv_val, sizeof(guid.info)); - printf("%s: %s\n", field, - smb_uuid_string_static(smb_uuid_unpack_static(guid))); + smb_uuid_unpack(guid, &tmp); + printf("%s: %s\n", field, smb_uuid_string(talloc_tos(), tmp)); } } @@ -3429,7 +3432,7 @@ const char *ads_get_extended_right_name_by_guid(ADS_STRUCT *ads, } expr = talloc_asprintf(mem_ctx, "(rightsGuid=%s)", - smb_uuid_string_static(*rights_guid)); + smb_uuid_string(mem_ctx, *rights_guid)); if (!expr) { goto done; } -- cgit From 6f46f75dfc2c80b99a6a5fb277bab456a5fd247b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 3 Dec 2007 17:17:05 -0800 Subject: Make strhex_to_str clear on string limits. Remove pstring from web/*.c Jeremy. (This used to be commit f9c8d62389f8cb47837e5360209936176537df13) --- source3/libads/ldap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 533aa3026f..a4ba3760c2 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2853,10 +2853,10 @@ bool ads_get_sid_from_extended_dn(TALLOC_CTX *mem_ctx, } break; case ADS_EXTENDED_DN_HEX_STRING: { - pstring buf; + fstring buf; size_t buf_len; - buf_len = strhex_to_str(buf, strlen(p), p); + buf_len = strhex_to_str(buf, sizeof(buf), p, strlen(p)); if (buf_len == 0) { return False; } -- cgit From 78c6ee0090f4122bc25baaacb5546517ad4b7bc6 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 24 Nov 2007 17:27:54 +0100 Subject: Remove some globals (This used to be commit 31d0a846db08d845e6cdfd85def4ac1c34031e02) --- source3/libads/dns.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/dns.c b/source3/libads/dns.c index cdc4b448cf..3239892814 100644 --- a/source3/libads/dns.c +++ b/source3/libads/dns.c @@ -709,7 +709,7 @@ static char *sitename_key(const char *realm) { char *keystr; - if (asprintf(&keystr, SITENAME_KEY, strupper_static(realm)) == -1) { + if (asprintf_strupper_m(&keystr, SITENAME_KEY, realm) == -1) { return NULL; } -- cgit From 8fd3a7c43e925e452b7738c50811d8a00b35babb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 6 Dec 2007 09:53:42 +0100 Subject: libads: fix typo metze (This used to be commit b55b19190d9c1199be13727a75a5936d6f5f15a8) --- source3/libads/sasl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 3b3838e390..798d0b4365 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -329,7 +329,7 @@ static ADS_STATUS ads_sasl_gssapi_unwrap(ADS_STRUCT *ads) return ADS_ERROR_NT(NT_STATUS_ACCESS_DENIED); } - if (wrapped.length < wrapped.length) { + if (wrapped.length < unwrapped.length) { return ADS_ERROR_NT(NT_STATUS_INTERNAL_ERROR); } -- cgit From d8ac0cecaeed2da19a286fcb4392bc6fbb10cd8b Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 6 Dec 2007 13:51:25 +0100 Subject: Remove an incredible amount of whitespace. Sorry - could not resist. Michael (This used to be commit 1000c98eae0886dbdf60beb1fe64d66ec009746b) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index a4ba3760c2..da4227b64c 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -42,7 +42,7 @@ #define LDAP_SERVER_TREE_DELETE_OID "1.2.840.113556.1.4.805" static SIG_ATOMIC_T gotalarm; - + /*************************************************************** Signal function to tell us we timed out. ****************************************************************/ -- cgit From 900288a2b86abd247f9eb4cd15dc5617a17cfef1 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 15 Dec 2007 21:11:36 +0100 Subject: Replace sid_string_static by sid_string_dbg in DEBUGs (This used to be commit bb35e794ec129805e874ceba882bcc1e84791a09) --- source3/libads/authdata.c | 13 ++++++++----- source3/libads/ldap.c | 4 ++-- 2 files changed, 10 insertions(+), 7 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c index db58cf0400..500f2d455e 100644 --- a/source3/libads/authdata.c +++ b/source3/libads/authdata.c @@ -742,14 +742,16 @@ void dump_pac_logon_info(int lvl, PAC_LOGON_INFO *logon_info) DEBUGADD(lvl,("\tUser Flags: LOGON_EXTRA_SIDS 0x%x (%d)\n", LOGON_EXTRA_SIDS, LOGON_EXTRA_SIDS)); if (user_flgs & LOGON_RESOURCE_GROUPS) DEBUGADD(lvl,("\tUser Flags: LOGON_RESOURCE_GROUPS 0x%x (%d)\n", LOGON_RESOURCE_GROUPS, LOGON_RESOURCE_GROUPS)); - DEBUGADD(lvl,("\tUser SID: %s-%d\n", sid_string_static(&dom_sid), logon_info->info3.user_rid)); - DEBUGADD(lvl,("\tGroup SID: %s-%d\n", sid_string_static(&dom_sid), logon_info->info3.group_rid)); + DEBUGADD(lvl,("\tUser SID: %s-%d\n", sid_string_dbg(&dom_sid), + logon_info->info3.user_rid)); + DEBUGADD(lvl,("\tGroup SID: %s-%d\n", sid_string_dbg(&dom_sid), + logon_info->info3.group_rid)); DEBUGADD(lvl,("\tGroup Membership (Global and Universal Groups of own domain):\n")); for (i = 0; i < logon_info->info3.num_groups; i++) { attr_string = pac_group_attr_string(logon_info->info3.gids[i].attr); DEBUGADD(lvl,("\t\t%d: sid: %s-%d\n\t\t attr: 0x%x == %s\n", - i, sid_string_static(&dom_sid), + i, sid_string_dbg(&dom_sid), logon_info->info3.gids[i].g_rid, logon_info->info3.gids[i].attr, attr_string)); @@ -760,7 +762,8 @@ void dump_pac_logon_info(int lvl, PAC_LOGON_INFO *logon_info) for (i = 0; i < logon_info->info3.num_other_sids; i++) { attr_string = pac_group_attr_string(logon_info->info3.other_sids_attrib[i]); DEBUGADD(lvl,("\t\t%d: sid: %s\n\t\t attr: 0x%x == %s\n", - i, sid_string_static(&logon_info->info3.other_sids[i].sid), + i, sid_string_dbg( + &logon_info->info3.other_sids[i].sid), logon_info->info3.other_sids_attrib[i], attr_string)); SAFE_FREE(attr_string); @@ -770,7 +773,7 @@ void dump_pac_logon_info(int lvl, PAC_LOGON_INFO *logon_info) for (i = 0; i < logon_info->info3.res_group_count; i++) { attr_string = pac_group_attr_string(logon_info->res_groups.group_membership[i].attrs); DEBUGADD(lvl,("\t\t%d: sid: %s-%d\n\t\t attr: 0x%x == %s\n", - i, sid_string_static(&res_group_dom_sid), + i, sid_string_dbg(&res_group_dom_sid), logon_info->res_groups.group_membership[i].rid, logon_info->res_groups.group_membership[i].attrs, attr_string)); diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index da4227b64c..a4532cd2ea 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2367,8 +2367,8 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) for (i=0; values[i]; i++) { ret = sid_parse(values[i]->bv_val, values[i]->bv_len, &(*sids)[count]); if (ret) { - fstring sid; - DEBUG(10, ("pulling SID: %s\n", sid_to_string(sid, &(*sids)[count]))); + DEBUG(10, ("pulling SID: %s\n", + sid_string_dbg(&(*sids)[count]))); count++; } } -- cgit From 54ae9dfcbce727ae3107f21eee68762502acda60 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 15 Dec 2007 21:49:15 +0100 Subject: Use sid_string_talloc where we have a tmp talloc ctx (This used to be commit 0a911d38b8f4be382a9df60f9c6de0c500464b3a) --- source3/libads/disp_sec.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/disp_sec.c b/source3/libads/disp_sec.c index e211ef69e4..f4c68638df 100644 --- a/source3/libads/disp_sec.c +++ b/source3/libads/disp_sec.c @@ -163,7 +163,7 @@ static void ads_disp_ace(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, SEC_ACE *sec_ace) } printf("access SID: %s\naccess type: %s\n", - sid_string_static(&sec_ace->trustee), access_type); + sid_string_talloc(mem_ctx, &sec_ace->trustee), access_type); if (sec_ace_object(sec_ace->type)) { ads_disp_sec_ace_object(ads, mem_ctx, &sec_ace->object.object); @@ -213,9 +213,9 @@ void ads_disp_sd(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, SEC_DESC *sd) sd->type); printf("owner SID: %s\n", sd->owner_sid ? - sid_string_static(sd->owner_sid) : "(null)"); + sid_string_talloc(mem_ctx, sd->owner_sid) : "(null)"); printf("group SID: %s\n", sd->group_sid ? - sid_string_static(sd->group_sid) : "(null)"); + sid_string_talloc(mem_ctx, sd->group_sid) : "(null)"); ads_disp_acl(sd->sacl, "system"); if (sd->sacl) { -- cgit From 14ef4cdec1ab6be55c97d0f32780cbddbcdde218 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 15 Dec 2007 22:00:39 +0100 Subject: Replace sid_string_static with sid_to_string This adds 28 fstrings on the stack, but I think an fstring on the stack is still far better than a static one. (This used to be commit c7c885078be8fd3024c186044ac28275d7609679) --- source3/libads/ldap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index a4532cd2ea..c3dd9154de 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1847,8 +1847,9 @@ static void dump_sid(ADS_STRUCT *ads, const char *field, struct berval **values) int i; for (i=0; values[i]; i++) { DOM_SID sid; + fstring tmp; sid_parse(values[i]->bv_val, values[i]->bv_len, &sid); - printf("%s: %s\n", field, sid_string_static(&sid)); + printf("%s: %s\n", field, sid_to_string(tmp, &sid)); } } -- cgit From 2e07c2ade89f4ff281c61f74cb88e09990cf5f46 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 15 Dec 2007 22:47:30 +0100 Subject: s/sid_to_string/sid_to_fstring/ least surprise for callers (This used to be commit eb523ba77697346a365589101aac379febecd546) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index c3dd9154de..e9124a387c 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1849,7 +1849,7 @@ static void dump_sid(ADS_STRUCT *ads, const char *field, struct berval **values) DOM_SID sid; fstring tmp; sid_parse(values[i]->bv_val, values[i]->bv_len, &sid); - printf("%s: %s\n", field, sid_to_string(tmp, &sid)); + printf("%s: %s\n", field, sid_to_fstring(tmp, &sid)); } } -- cgit From 5dbc4a23bcae0087ab4319b5343cf6f44a4819e3 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 15 Dec 2007 23:22:25 -0800 Subject: Added patch originally by Andreas Schneider to cause us to behave like Vista when looking for remote machine principal. Modified by me. Jeremy. (This used to be commit d0e33840fb4cfc85990d3ee327428b0854a22722) --- source3/libads/kerberos.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 29e5661d3c..02e14f468d 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -487,6 +487,58 @@ char* kerberos_secrets_fetch_des_salt( void ) return salt; } +/************************************************************************ + Routine to get the default realm from the kerberos credentials cache. + Caller must free if the return value is not NULL. +************************************************************************/ + +char *kerberos_get_default_realm_from_ccache( void ) +{ + char *realm = NULL; + krb5_context ctx = NULL; + krb5_ccache cc = NULL; + krb5_principal princ = NULL; + + initialize_krb5_error_table(); + if (krb5_init_context(&ctx)) { + return NULL; + } + + DEBUG(5,("kerberos_get_default_realm_from_ccache: " + "Trying to read krb5 cache: %s\n", + krb5_cc_default_name(ctx))); + if (krb5_cc_default(ctx, &cc)) { + DEBUG(0,("kerberos_get_default_realm_from_ccache: " + "failed to read default cache\n")); + goto out; + } + if (krb5_cc_get_principal(ctx, cc, &princ)) { + DEBUG(0,("kerberos_get_default_realm_from_ccache: " + "failed to get default principal\n")); + goto done; + } + +#if defined(HAVE_KRB5_PRINCIPAL_GET_REALM) + realm = SMB_STRDUP(krb5_principal_get_realm(ctx, princ)); +#elif defined(HAVE_KRB5_PRINC_REALM) + realm = SMB_STRDUP(krb5_princ_realm(ctx, princ)->data); +#endif + + out: + + if (princ) { + krb5_free_principal(ctx, princ); + } + if (cc) { + krb5_cc_close(ctx, cc); + } + if (ctx) { + krb5_free_context(ctx); + } +done: + return realm; +} + /************************************************************************ Routine to get the salting principal for this service. This is -- cgit From 8e86b7bb6569fea9f974eb3da68bc282dde068d0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 15 Dec 2007 23:32:28 -0800 Subject: Doh, fix typo in error exit. Jeremy. (This used to be commit 44918f39c0598eec681eb9e5c65452f04809c375) --- source3/libads/kerberos.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 02e14f468d..227f95d15e 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -515,7 +515,7 @@ char *kerberos_get_default_realm_from_ccache( void ) if (krb5_cc_get_principal(ctx, cc, &princ)) { DEBUG(0,("kerberos_get_default_realm_from_ccache: " "failed to get default principal\n")); - goto done; + goto out; } #if defined(HAVE_KRB5_PRINCIPAL_GET_REALM) @@ -535,7 +535,7 @@ char *kerberos_get_default_realm_from_ccache( void ) if (ctx) { krb5_free_context(ctx); } -done: + return realm; } -- cgit From d365a43785238fc59f2fd8a262d30a2a1aae7078 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 16 Dec 2007 14:15:16 +0100 Subject: make use of unmarshall_sec_desc (This used to be commit ced0c42f055a672f6b4ab6ba809b0f63c83b431e) --- source3/libads/ldap.c | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index e9124a387c..348ccacaee 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1858,31 +1858,24 @@ static void dump_sid(ADS_STRUCT *ads, const char *field, struct berval **values) */ static void dump_sd(ADS_STRUCT *ads, const char *filed, struct berval **values) { - prs_struct ps; - - SEC_DESC *psd = 0; - TALLOC_CTX *ctx = 0; - - if (!(ctx = talloc_init("sec_io_desc"))) - return; + TALLOC_CTX *frame = talloc_stackframe(); + struct security_descriptor *psd; + NTSTATUS status; - /* prepare data */ - prs_init(&ps, values[0]->bv_len, ctx, UNMARSHALL); - prs_copy_data_in(&ps, values[0]->bv_val, values[0]->bv_len); - prs_set_offset(&ps,0); - - /* parse secdesc */ - if (!sec_io_desc("sd", &psd, &ps, 1)) { - prs_mem_free(&ps); - talloc_destroy(ctx); + status = unmarshall_sec_desc(talloc_tos(), (uint8 *)values[0]->bv_val, + values[0]->bv_len, &psd); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("unmarshall_sec_desc failed: %s\n", + nt_errstr(status))); + TALLOC_FREE(frame); return; } + if (psd) { - ads_disp_sd(ads, ctx, psd); + ads_disp_sd(ads, talloc_tos(), psd); } - prs_mem_free(&ps); - talloc_destroy(ctx); + TALLOC_FREE(frame); } /* -- cgit From 4869ccfed6ba8c44fb49844a5a8abbb671518954 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mon, 17 Dec 2007 15:21:38 -0500 Subject: While 'data' is usually 0 terminated, nothing in the spec requires that. The correct way is to copy only 'length' bytes. Simo. (This used to be commit 814c1b0e0034fb67c7718760dfcf913904f3e7fa) --- source3/libads/kerberos.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 227f95d15e..4fc23956bd 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -521,7 +521,10 @@ char *kerberos_get_default_realm_from_ccache( void ) #if defined(HAVE_KRB5_PRINCIPAL_GET_REALM) realm = SMB_STRDUP(krb5_principal_get_realm(ctx, princ)); #elif defined(HAVE_KRB5_PRINC_REALM) - realm = SMB_STRDUP(krb5_princ_realm(ctx, princ)->data); + { + krb5_data *realm_data = krb5_princ_realm(ctx, princ); + realm = SMB_STRNDUP(realm_data->data, realm_data->length); + } #endif out: -- cgit From afc93255d183eefb68e45b8ec6275f6a62cf9795 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 26 Dec 2007 17:12:36 -0800 Subject: Add SMB encryption. Still fixing client decrypt but negotiation works. Jeremy. (This used to be commit d78045601af787731f0737b8627450018902b104) --- source3/libads/ads_status.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ads_status.c b/source3/libads/ads_status.c index ecef9d224b..29148e8543 100644 --- a/source3/libads/ads_status.c +++ b/source3/libads/ads_status.c @@ -141,3 +141,12 @@ const char *ads_errstr(ADS_STATUS status) } } +#ifdef HAVE_GSSAPI +NTSTATUS gss_err_to_ntstatus(uint32 maj, uint32 min) +{ + ADS_STATUS adss = ADS_ERROR_GSS(maj, min); + DEBUG(10,("gss_err_to_ntstatus: Error %s\n", + ads_errstr(adss) )); + return ads_ntstatus(adss); +} +#endif -- cgit From 240391be5345aef88a25c1221942202ba33588b8 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 29 Dec 2007 22:47:03 +0100 Subject: Make use of [un]marshall_sec_desc (This used to be commit 54576733d6c0511dc7379f964b1cb035913b7c8d) --- source3/libads/ldap.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 348ccacaee..953693ce48 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2384,20 +2384,22 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) LDAPMessage *msg, const char *field, SEC_DESC **sd) { struct berval **values; - bool ret = False; + bool ret = true; values = ldap_get_values_len(ads->ldap.ld, msg, field); - if (!values) return False; + if (!values) return false; if (values[0]) { - prs_struct ps; - prs_init(&ps, values[0]->bv_len, mem_ctx, UNMARSHALL); - prs_copy_data_in(&ps, values[0]->bv_val, values[0]->bv_len); - prs_set_offset(&ps,0); - - ret = sec_io_desc("sd", sd, &ps, 1); - prs_mem_free(&ps); + NTSTATUS status; + status = unmarshall_sec_desc(mem_ctx, + (uint8 *)values[0]->bv_val, + values[0]->bv_len, sd); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("unmarshall_sec_desc failed: %s\n", + nt_errstr(status))); + ret = false; + } } ldap_value_free_len(values); -- cgit From b076a7e802a89bdc5b369e98c7d69d8f970d8265 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 3 Jan 2008 17:28:09 +0100 Subject: Add ads_get_joinable_ous(). Guenther (This used to be commit 5bbceac88159ef6ff83d9cc62c77c7af2116967d) --- source3/libads/ldap.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 953693ce48..843d57988c 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2790,6 +2790,66 @@ ADS_STATUS ads_upn_suffixes(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char ***suffix return status; } +/** + * get the joinable ous for a domain + * @param ads connection to ads server + * @param mem_ctx Pointer to talloc context + * @param ous Pointer to an array of ous + * @param num_ous Pointer to the number of ous + * @return status of search + **/ +ADS_STATUS ads_get_joinable_ous(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + char ***ous, + size_t *num_ous) +{ + ADS_STATUS status; + LDAPMessage *res = NULL; + LDAPMessage *msg = NULL; + const char *attrs[] = { "dn", NULL }; + int count = 0; + + status = ads_search(ads, &res, + "(|(objectClass=domain)(objectclass=organizationalUnit))", + attrs); + if (!ADS_ERR_OK(status)) { + return status; + } + + count = ads_count_replies(ads, res); + if (count < 1) { + ads_msgfree(ads, res); + return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); + } + + for (msg = ads_first_entry(ads, res); msg; + msg = ads_next_entry(ads, msg)) { + + char *dn = NULL; + + dn = ads_get_dn(ads, msg); + if (!dn) { + ads_msgfree(ads, res); + return ADS_ERROR(LDAP_NO_MEMORY); + } + + if (!add_string_to_array(mem_ctx, dn, + (const char ***)ous, + (int *)num_ous)) { + ads_memfree(ads, dn); + ads_msgfree(ads, res); + return ADS_ERROR(LDAP_NO_MEMORY); + } + + ads_memfree(ads, dn); + } + + ads_msgfree(ads, res); + + return status; +} + + /** * pull a DOM_SID from an extended dn string * @param mem_ctx TALLOC_CTX -- cgit From 3f42428f9bca5b8473501adc932405cae3c247bb Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 4 Jan 2008 21:45:28 +0100 Subject: Fix a misleading DEBUG message. At this stage, the (tcp) connection to the LDAP server has not been established, this is what is about to be attempted. What has been succesfully done, is a CLDAP netlogon query. Michael (This used to be commit 71c3c8ad4c92c5f6267b84ee1d207e5e49e9a4ec) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 843d57988c..138dfe9015 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -400,7 +400,7 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) got_connection: print_sockaddr(addr, sizeof(addr), &ads->ldap.ss); - DEBUG(3,("Connected to LDAP server %s\n", addr)); + DEBUG(3,("Successfully contacted LDAP server %s\n", addr)); if (!ads->auth.user_name) { /* Must use the userPrincipalName value here or sAMAccountName -- cgit From 4ad3464fb94c7088e7fd731113c682aa7756ef01 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 4 Jan 2008 21:53:25 +0100 Subject: Unindent function header. Michael (This used to be commit cafda34783f0961c9b463803c19cfcb69f836e3f) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 138dfe9015..712e7e2889 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -52,7 +52,7 @@ static void gotalarm_sig(void) gotalarm = 1; } - LDAP *ldap_open_with_timeout(const char *server, int port, unsigned int to) +LDAP *ldap_open_with_timeout(const char *server, int port, unsigned int to) { LDAP *ldp = NULL; -- cgit From 34e579fce5a6cc9ffa60fbe6e797b2e6b35c879e Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 4 Jan 2008 21:54:02 +0100 Subject: Enhance DEBUG-verbosity of ldap_open_with_timeout(). Michael (This used to be commit 9e70d1f24dd304c363a1bde97b5af618b46edc49) --- source3/libads/ldap.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 712e7e2889..8a2b82a61d 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -56,6 +56,10 @@ LDAP *ldap_open_with_timeout(const char *server, int port, unsigned int to) { LDAP *ldp = NULL; + + DEBUG(10, ("Opening connection to LDAP server '%s:%d', timeout " + "%u seconds\n", server, port, to)); + /* Setup timeout */ gotalarm = 0; CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig); @@ -65,8 +69,10 @@ LDAP *ldap_open_with_timeout(const char *server, int port, unsigned int to) ldp = ldap_open(server, port); if (ldp == NULL) { - DEBUG(2,("Could not open LDAP connection to %s:%d: %s\n", + DEBUG(2,("Could not open connection to LDAP server %s:%d: %s\n", server, port, strerror(errno))); + } else { + DEBUG(10, ("Connected to LDAP server '%s:%d'\n", server, port)); } /* Teardown timeout. */ -- cgit From 2cb68e3898046ea0dd2ddcf1e32dc7dffca79be8 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 4 Jan 2008 21:56:57 +0100 Subject: Untangle assignment and result check. Michael (This used to be commit 465a3b356cffb855e26569d3752f15cac07208c0) --- source3/libads/ldap.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 8a2b82a61d..ae8e1e4d4d 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -448,9 +448,9 @@ got_connection: /* Otherwise setup the TCP LDAP session */ - if ( (ads->ldap.ld = ldap_open_with_timeout(ads->config.ldap_server_name, - LDAP_PORT, lp_ldap_timeout())) == NULL ) - { + ads->ldap.ld = ldap_open_with_timeout(ads->config.ldap_server_name, + LDAP_PORT, lp_ldap_timeout()); + if (ads->ldap.ld == NULL) { return ADS_ERROR(LDAP_OPERATIONS_ERROR); } -- cgit From b54310cbaa9584a46decfa2a5bc4bb2a72381a98 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 4 Jan 2008 22:06:15 +0100 Subject: Add a debug message (when the LDAP server has really been connected). Michael (This used to be commit 7d9d2de39072b3291b95ac3965df0d19f83792b9) --- source3/libads/ldap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index ae8e1e4d4d..44560c852d 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -453,6 +453,7 @@ got_connection: if (ads->ldap.ld == NULL) { return ADS_ERROR(LDAP_OPERATIONS_ERROR); } + DEBUG(3,("Connected to LDAP server %s\n", ads->config.ldap_server_name)); /* cache the successful connection for workgroup and realm */ if (ads_closest_dc(ads)) { -- cgit From 4aba7475effff485f265fb975cf467fffd6c7db0 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 4 Jan 2008 22:56:10 +0100 Subject: Re-Indent function ldap_open_with_timeout(). This reverts commit #cafda34783f0961c9b463803c19cfcb69f836e3f . I just learned (the hard way) that these indeted functions are not indented by accident but that the intention of this is to not include the prototype into proto.h. Michael (This used to be commit 2e5d01b2146bb9e057b2779d9fe7691ed46d9f45) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 44560c852d..975e926864 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -52,7 +52,7 @@ static void gotalarm_sig(void) gotalarm = 1; } -LDAP *ldap_open_with_timeout(const char *server, int port, unsigned int to) + LDAP *ldap_open_with_timeout(const char *server, int port, unsigned int to) { LDAP *ldp = NULL; -- cgit From f89fa0a6f85b74469519ba97752f45db8b879689 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 8 Jan 2008 13:46:54 +0100 Subject: Do not ignore provided machine_name in ads_get_upn(). Guenther (This used to be commit ddc1307844379f99b3dde48fc351d0326d22a7ce) --- source3/libads/ldap.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 975e926864..28bc7793d7 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -3026,26 +3026,26 @@ char* ads_get_upn( ADS_STRUCT *ads, TALLOC_CTX *ctx, const char *machine_name ) ADS_STATUS status; int count = 0; char *name = NULL; - - status = ads_find_machine_acct(ads, &res, global_myname()); + + status = ads_find_machine_acct(ads, &res, machine_name); if (!ADS_ERR_OK(status)) { DEBUG(0,("ads_get_upn: Failed to find account for %s\n", global_myname())); goto out; } - + if ( (count = ads_count_replies(ads, res)) != 1 ) { DEBUG(1,("ads_get_upn: %d entries returned!\n", count)); goto out; } - + if ( (name = ads_pull_string(ads, ctx, res, "userPrincipalName")) == NULL ) { DEBUG(2,("ads_get_upn: No userPrincipalName attribute!\n")); } out: ads_msgfree(ads, res); - + return name; } -- cgit From 866af9a800cbfc022ce6144ee706c0826eb6c39b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 11 Jan 2008 23:43:33 -0800 Subject: Coverity 512, uninitialized var. Jeremy. (This used to be commit 1b7cc80c61ccbf766801080f5a3f0260f40ccc17) --- source3/libads/authdata.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c index 500f2d455e..9a6f1061df 100644 --- a/source3/libads/authdata.c +++ b/source3/libads/authdata.c @@ -214,7 +214,7 @@ static bool pac_io_group_membership_array(const char *desc, static bool pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info, prs_struct *ps, int depth) { - uint32 garbage, i; + uint32 garbage = 0, i; if (NULL == info) return False; @@ -398,7 +398,7 @@ static bool pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info, static bool pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info, prs_struct *ps, int depth) { - uint32 garbage; + uint32 garbage = 0; bool kerb_validation_info = True; if (NULL == info) -- cgit From 43717a16e2fca8b196d4a89e33b05fefc0cb02d2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 11 Jan 2008 23:53:27 -0800 Subject: Fix CID 476. Ensure a valid pac_data pointer is always passed to ads_verify_ticket as it's always derefed. Jeremy. (This used to be commit 0599d57efff0f417f75510e8b08c3cb7b4bcfcd8) --- source3/libads/kerberos_verify.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 7040093e90..5ce7aa6b45 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -501,8 +501,7 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, DEBUG(3,("ads_verify_ticket: did not retrieve auth data. continuing without PAC\n")); } - if (got_auth_data && pac_data != NULL) { - + if (got_auth_data) { pac_ret = decode_pac_data(mem_ctx, &auth_data, context, keyblock, client_principal, authtime, pac_data); if (!NT_STATUS_IS_OK(pac_ret)) { DEBUG(3,("ads_verify_ticket: failed to decode PAC_DATA: %s\n", nt_errstr(pac_ret))); -- cgit From a32cca7f372217e483ffda059e7775e3327982cc Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 14 Jan 2008 14:18:53 +0100 Subject: Print principal in debug statement in kerberos_kinit_password() as well. Guenther (This used to be commit 44d67e84625a2a1a93baecef0e418b48e982443b) --- source3/libads/kerberos.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 4fc23956bd..e9222e8401 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -209,7 +209,8 @@ int kerberos_kinit_password_ext(const char *principal, krb5_set_real_time(ctx, time(NULL) + time_offset, 0); } - DEBUG(10,("kerberos_kinit_password: using [%s] as ccache and config [%s]\n", + DEBUG(10,("kerberos_kinit_password: as %s using [%s] as ccache and config [%s]\n", + principal, cache_name ? cache_name: krb5_cc_default_name(ctx), getenv("KRB5_CONFIG"))); -- cgit From fbcc7820c620d45f02ab75e08d840e3a676fe671 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 16 Jan 2008 15:51:52 +0100 Subject: Fix memleak in ads_build_path(). Guenther (This used to be commit b7a06b54e0a58c4cd6c5351b1e4a0a2c253cfea1) --- source3/libads/ads_struct.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index 041878916e..44bcdf76ea 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -32,18 +32,23 @@ char *ads_build_path(const char *realm, const char *sep, const char *field, int r = SMB_STRDUP(realm); - if (!r || !*r) + if (!r || !*r) { return r; + } - for (p=r; *p; p++) - if (strchr(sep, *p)) + for (p=r; *p; p++) { + if (strchr(sep, *p)) { numbits++; + } + } len = (numbits+1)*(strlen(field)+1) + strlen(r) + 1; ret = (char *)SMB_MALLOC(len); - if (!ret) + if (!ret) { + free(r); return NULL; + } strlcpy(ret,field, len); p=strtok(r,sep); @@ -57,7 +62,8 @@ char *ads_build_path(const char *realm, const char *sep, const char *field, int else asprintf(&s, "%s,%s%s", ret, field, p); free(ret); - ret = s; + ret = SMB_STRDUP(s); + free(s); } } -- cgit From bd8abea49fed09e131ab5162821b0ed05c1ab1b0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 16 Jan 2008 13:21:46 -0800 Subject: Fix IPv6 bug #5204, which caused krb5 DNS lookups for a name '['. Jeremy. (This used to be commit f2aa921505e49f894bfed4e5e2f9fc01918b1bb0) --- source3/libads/kerberos.c | 69 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 13 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index e9222e8401..f7e947b1e7 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -25,6 +25,8 @@ #ifdef HAVE_KRB5 +#define DEFAULT_KRB5_PORT 88 + #define LIBADS_CCACHE_NAME "MEMORY:libads" /* @@ -665,6 +667,51 @@ int kerberos_kinit_password(const char *principal, NULL); } +/************************************************************************ +************************************************************************/ + +static char *print_kdc_line(char *mem_ctx, + const char *prev_line, + const struct sockaddr_storage *pss) +{ + char *kdc_str = NULL; + + if (pss->ss_family == AF_INET) { + kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n", + prev_line, + print_canonical_sockaddr(mem_ctx, pss)); + } else { + char addr[INET6_ADDRSTRLEN]; + uint16_t port = get_sockaddr_port(pss); + + if (port != 0 && port != DEFAULT_KRB5_PORT) { + /* Currently for IPv6 we can't specify a non-default + krb5 port with an address, as this requires a ':'. + Resolve to a name. */ + char hostname[MAX_DNS_NAME_LENGTH]; + if (sys_getnameinfo((const struct sockaddr *)pss, + sizeof(*pss), + hostname, sizeof(hostname), + NULL, 0, + NI_NAMEREQD) == 0) { + /* Success, use host:port */ + kdc_str = talloc_asprintf(mem_ctx, + "%s\tkdc = %s:%u\n", + prev_line, + hostname, + (unsigned int)port); + return kdc_str; + } + } + kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n", + prev_line, + print_sockaddr(addr, + sizeof(addr), + pss)); + } + return kdc_str; +} + /************************************************************************ Create a string list of available kdc's, possibly searching by sitename. Does DNS queries. @@ -677,12 +724,10 @@ static char *get_kdc_ip_string(char *mem_ctx, { int i; struct ip_service *ip_srv_site = NULL; - struct ip_service *ip_srv_nonsite; + struct ip_service *ip_srv_nonsite = NULL; int count_site = 0; int count_nonsite; - char *kdc_str = talloc_asprintf(mem_ctx, "\tkdc = %s\n", - print_canonical_sockaddr(mem_ctx, - pss)); + char *kdc_str = print_kdc_line(mem_ctx, "", pss); if (kdc_str == NULL) { return NULL; @@ -700,10 +745,9 @@ static char *get_kdc_ip_string(char *mem_ctx, } /* Append to the string - inefficient * but not done often. */ - kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n", - kdc_str, - print_canonical_sockaddr(mem_ctx, - &ip_srv_site[i].ss)); + kdc_str = print_kdc_line(mem_ctx, + kdc_str, + &ip_srv_site[i].ss); if (!kdc_str) { SAFE_FREE(ip_srv_site); return NULL; @@ -738,10 +782,9 @@ static char *get_kdc_ip_string(char *mem_ctx, } /* Append to the string - inefficient but not done often. */ - kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n", + kdc_str = print_kdc_line(mem_ctx, kdc_str, - print_canonical_sockaddr(mem_ctx, - &ip_srv_nonsite[i].ss)); + &ip_srv_nonsite[i].ss); if (!kdc_str) { SAFE_FREE(ip_srv_site); SAFE_FREE(ip_srv_nonsite); @@ -873,8 +916,8 @@ bool create_local_private_krb5_conf_for_domain(const char *realm, } DEBUG(5,("create_local_private_krb5_conf_for_domain: wrote " - "file %s with realm %s KDC = %s\n", - fname, realm_upper, print_canonical_sockaddr(dname, pss) )); + "file %s with realm %s KDC list = %s\n", + fname, realm_upper, kdc_ip_string)); /* Set the environment variable to this file. */ setenv("KRB5_CONFIG", fname, 1); -- cgit From 70426bdd307be2bbaa2ec6f111440bae69216933 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 16 Jan 2008 13:28:24 -0800 Subject: Tidy up code and debug for non-default krb5 IPv6 port. Jeremy. (This used to be commit 79b7972de4c2a8c71e37642ddf7e5bbed53dd58a) --- source3/libads/kerberos.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index f7e947b1e7..b99525047f 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -689,25 +689,31 @@ static char *print_kdc_line(char *mem_ctx, krb5 port with an address, as this requires a ':'. Resolve to a name. */ char hostname[MAX_DNS_NAME_LENGTH]; - if (sys_getnameinfo((const struct sockaddr *)pss, + int ret = sys_getnameinfo((const struct sockaddr *)pss, sizeof(*pss), hostname, sizeof(hostname), NULL, 0, - NI_NAMEREQD) == 0) { - /* Success, use host:port */ - kdc_str = talloc_asprintf(mem_ctx, + NI_NAMEREQD); + if (ret) { + DEBUG(0,("print_kdc_line: can't resolve name " + "for kdc with non-default port %s. " + "Error %s\n.", + print_canonical_sockaddr(mem_ctx, pss), + gai_strerror(ret))); + } + /* Success, use host:port */ + kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s:%u\n", - prev_line, + prev_line, hostname, (unsigned int)port); - return kdc_str; - } - } - kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n", + } else { + kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n", prev_line, print_sockaddr(addr, sizeof(addr), pss)); + } } return kdc_str; } -- cgit From a92eb76688600efbf4a4056c2543f348e2fee8aa Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 17 Jan 2008 10:24:34 +0100 Subject: Finally enable pidl generated SAMR & NETLOGON headers and clients. Guenther (This used to be commit f7100156a7df7ac3ae84e45a47153b38d9375215) --- source3/libads/authdata.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c index 9a6f1061df..644f8515bc 100644 --- a/source3/libads/authdata.c +++ b/source3/libads/authdata.c @@ -429,8 +429,8 @@ static bool pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info, if (info->info3.ptr_res_groups) { - if (!(info->info3.user_flgs & LOGON_RESOURCE_GROUPS)) { - DEBUG(0,("user_flgs attribute does not have LOGON_RESOURCE_GROUPS\n")); + if (!(info->info3.user_flgs & NETLOGON_RESOURCE_GROUPS)) { + DEBUG(0,("user_flgs attribute does not have NETLOGON_RESOURCE_GROUPS\n")); /* return False; */ } @@ -738,10 +738,10 @@ void dump_pac_logon_info(int lvl, PAC_LOGON_INFO *logon_info) DEBUG(lvl,("The PAC:\n")); DEBUGADD(lvl,("\tUser Flags: 0x%x (%d)\n", user_flgs, user_flgs)); - if (user_flgs & LOGON_EXTRA_SIDS) - DEBUGADD(lvl,("\tUser Flags: LOGON_EXTRA_SIDS 0x%x (%d)\n", LOGON_EXTRA_SIDS, LOGON_EXTRA_SIDS)); - if (user_flgs & LOGON_RESOURCE_GROUPS) - DEBUGADD(lvl,("\tUser Flags: LOGON_RESOURCE_GROUPS 0x%x (%d)\n", LOGON_RESOURCE_GROUPS, LOGON_RESOURCE_GROUPS)); + if (user_flgs & NETLOGON_EXTRA_SIDS) + DEBUGADD(lvl,("\tUser Flags: NETLOGON_EXTRA_SIDS 0x%x (%d)\n", NETLOGON_EXTRA_SIDS, NETLOGON_EXTRA_SIDS)); + if (user_flgs & NETLOGON_RESOURCE_GROUPS) + DEBUGADD(lvl,("\tUser Flags: NETLOGON_RESOURCE_GROUPS 0x%x (%d)\n", NETLOGON_RESOURCE_GROUPS, NETLOGON_RESOURCE_GROUPS)); DEBUGADD(lvl,("\tUser SID: %s-%d\n", sid_string_dbg(&dom_sid), logon_info->info3.user_rid)); DEBUGADD(lvl,("\tGroup SID: %s-%d\n", sid_string_dbg(&dom_sid), -- cgit From 587cf54c61c9f1f7bcae431a82035fd942716c32 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 23 Jan 2008 11:04:10 +0100 Subject: strtok -> strtok_r (This used to be commit fd34ce437057bb34cdc37f4b066e424000d36789) --- source3/libads/ads_struct.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index 44bcdf76ea..8cc2f1215e 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -29,7 +29,8 @@ char *ads_build_path(const char *realm, const char *sep, const char *field, int int numbits = 0; char *ret; int len; - + char *saveptr; + r = SMB_STRDUP(realm); if (!r || !*r) { @@ -51,11 +52,11 @@ char *ads_build_path(const char *realm, const char *sep, const char *field, int } strlcpy(ret,field, len); - p=strtok(r,sep); + p=strtok_r(r, sep, &saveptr); if (p) { strlcat(ret, p, len); - while ((p=strtok(NULL,sep))) { + while ((p=strtok_r(NULL, sep, &saveptr)) != NULL) { char *s; if (reverse) asprintf(&s, "%s%s,%s", field, p, ret); -- cgit From c0c93dc2ba8bf6b32b0bcc228d947ee588ee4099 Mon Sep 17 00:00:00 2001 From: "Gerald W. Carter" Date: Mon, 28 Jan 2008 11:32:09 -0600 Subject: Restrict the enctypes in the generated krb5.conf files to Win2003 types. This fixes the failure observed on FC8 when joining a Windows 2008 RC1 domain. We currently do not handle user session keys correctly when the KDC uses AES in the ticket replies. (This used to be commit 8039a2518caae54bc876368c73ec493f3cd4eb73) --- source3/libads/kerberos.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index b99525047f..d47e8a3ff1 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -865,10 +865,14 @@ bool create_local_private_krb5_conf_for_domain(const char *realm, return False; } - file_contents = talloc_asprintf(fname, "[libdefaults]\n\tdefault_realm = %s\n\n" - "[realms]\n\t%s = {\n" - "\t%s\t}\n", - realm_upper, realm_upper, kdc_ip_string); + file_contents = talloc_asprintf(fname, + "[libdefaults]\n\tdefault_realm = %s\n" + "default_tgs_enctypes = RC4-HMAC DES-CBC-CRC DES-CBC-MD5\n" + "default_tkt_enctypes = RC4-HMAC DES-CBC-CRC DES-CBC-MD5\n" + "preferred_enctypes = RC4-HMAC DES-CBC-CRC DES-CBC-MD5\n\n" + "[realms]\n\t%s = {\n" + "\t%s\t}\n", + realm_upper, realm_upper, kdc_ip_string); if (!file_contents) { TALLOC_FREE(dname); -- cgit From 7cab0f5c0c3edc3eb74e3ae8fa5a649187dc99c1 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 29 Jan 2008 14:47:47 +0100 Subject: Fix the build. Avoid unrequired ndr_print_ads_struct dependencies. Guenther (This used to be commit c832882e49ff0dac6a717819dda24ab814253b2f) --- source3/libads/ndr.c | 118 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 source3/libads/ndr.c (limited to 'source3/libads') diff --git a/source3/libads/ndr.c b/source3/libads/ndr.c new file mode 100644 index 0000000000..6324a22041 --- /dev/null +++ b/source3/libads/ndr.c @@ -0,0 +1,118 @@ +/* + Unix SMB/CIFS implementation. + + debug print helpers + + Copyright (C) Guenther Deschner 2008 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "includes.h" + +void ndr_print_ads_auth_flags(struct ndr_print *ndr, const char *name, uint32_t r) +{ + ndr_print_uint32(ndr, name, r); + ndr->depth++; + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "ADS_AUTH_DISABLE_KERBEROS", ADS_AUTH_DISABLE_KERBEROS, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "ADS_AUTH_NO_BIND", ADS_AUTH_NO_BIND, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "ADS_AUTH_ANON_BIND", ADS_AUTH_ANON_BIND, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "ADS_AUTH_SIMPLE_BIND", ADS_AUTH_SIMPLE_BIND, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "ADS_AUTH_ALLOW_NTLMSSP", ADS_AUTH_ALLOW_NTLMSSP, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "ADS_AUTH_SASL_SIGN", ADS_AUTH_SASL_SIGN, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "ADS_AUTH_SASL_SEAL", ADS_AUTH_SASL_SEAL, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "ADS_AUTH_SASL_FORCE", ADS_AUTH_SASL_FORCE, r); + ndr->depth--; +} + +void ndr_print_ads_struct(struct ndr_print *ndr, const char *name, const struct ads_struct *r) +{ + if (!r) { return; } + + ndr_print_struct(ndr, name, "ads_struct"); + ndr->depth++; + ndr_print_bool(ndr, "is_mine", r->is_mine); + ndr_print_struct(ndr, name, "server"); + ndr->depth++; + ndr_print_string(ndr, "realm", r->server.realm); + ndr_print_string(ndr, "workgroup", r->server.workgroup); + ndr_print_string(ndr, "ldap_server", r->server.ldap_server); + ndr_print_bool(ndr, "foreign", r->server.foreign); + ndr->depth--; + ndr_print_struct(ndr, name, "auth"); + ndr->depth++; + ndr_print_string(ndr, "realm", r->auth.realm); +#ifdef DEBUG_PASSWORD + ndr_print_string(ndr, "password", r->auth.password); +#else + ndr_print_string(ndr, "password", "(PASSWORD ommited)"); +#endif + ndr_print_string(ndr, "user_name", r->auth.user_name); + ndr_print_string(ndr, "kdc_server", r->auth.kdc_server); + ndr_print_ads_auth_flags(ndr, "flags", r->auth.flags); + ndr_print_uint32(ndr, "time_offset", r->auth.time_offset); + ndr_print_time_t(ndr, "tgt_expire", r->auth.tgt_expire); + ndr_print_time_t(ndr, "tgs_expire", r->auth.tgs_expire); + ndr_print_time_t(ndr, "renewable", r->auth.renewable); + ndr->depth--; + ndr_print_struct(ndr, name, "config"); + ndr->depth++; + ndr_print_netr_DsR_DcFlags(ndr, "flags", r->config.flags); + ndr_print_string(ndr, "realm", r->config.realm); + ndr_print_string(ndr, "bind_path", r->config.bind_path); + ndr_print_string(ndr, "ldap_server_name", r->config.ldap_server_name); + ndr_print_string(ndr, "server_site_name", r->config.server_site_name); + ndr_print_string(ndr, "client_site_name", r->config.client_site_name); + ndr_print_time_t(ndr, "current_time", r->config.current_time); + ndr_print_bool(ndr, "tried_closest_dc", r->config.tried_closest_dc); + ndr_print_string(ndr, "schema_path", r->config.schema_path); + ndr_print_string(ndr, "config_path", r->config.config_path); + ndr->depth--; +#ifdef HAVE_LDAP + ndr_print_struct(ndr, name, "ldap"); + ndr->depth++; + ndr_print_ptr(ndr, "ld", r->ldap.ld); + ndr_print_sockaddr_storage(ndr, "ss", &r->ldap.ss); + ndr_print_time_t(ndr, "last_attempt", r->ldap.last_attempt); + ndr_print_uint32(ndr, "port", r->ldap.port); + ndr_print_uint16(ndr, "wrap_type", r->ldap.wrap_type); +#ifdef HAVE_LDAP_SASL_WRAPPING + ndr_print_ptr(ndr, "sbiod", r->ldap.sbiod); +#endif /* HAVE_LDAP_SASL_WRAPPING */ + ndr_print_ptr(ndr, "mem_ctx", r->ldap.mem_ctx); + ndr_print_ptr(ndr, "wrap_ops", r->ldap.wrap_ops); + ndr_print_ptr(ndr, "wrap_private_data", r->ldap.wrap_private_data); + ndr_print_struct(ndr, name, "in"); + ndr->depth++; + ndr_print_uint32(ndr, "ofs", r->ldap.in.ofs); + ndr_print_uint32(ndr, "needed", r->ldap.in.needed); + ndr_print_uint32(ndr, "left", r->ldap.in.left); + ndr_print_uint32(ndr, "max_wrapped", r->ldap.in.max_wrapped); + ndr_print_uint32(ndr, "min_wrapped", r->ldap.in.min_wrapped); + ndr_print_uint32(ndr, "size", r->ldap.in.size); + ndr_print_array_uint8(ndr, "buf", r->ldap.in.buf, r->ldap.in.size); + ndr->depth--; + ndr_print_struct(ndr, name, "out"); + ndr->depth++; + ndr_print_uint32(ndr, "ofs", r->ldap.out.ofs); + ndr_print_uint32(ndr, "left", r->ldap.out.left); + ndr_print_uint32(ndr, "max_unwrapped", r->ldap.out.max_unwrapped); + ndr_print_uint32(ndr, "sig_size", r->ldap.out.sig_size); + ndr_print_uint32(ndr, "size", r->ldap.out.size); + ndr_print_array_uint8(ndr, "buf", r->ldap.out.buf, r->ldap.out.size); + ndr->depth--; + ndr->depth--; +#endif /* HAVE_LDAP */ + ndr->depth--; +} -- cgit From 6c764172e541decc0fa4b0314f4d26ea859c0dfe Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 31 Jan 2008 01:50:49 +0100 Subject: When running with debug level > 10, dump ads_struct in ads_connect(). Guenther (This used to be commit 2dd7c64fa8845fe502789068b877f5eaf060afc7) --- source3/libads/ldap.c | 42 +++++++++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 9 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 28bc7793d7..7b0adc2fc3 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -391,6 +391,13 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) /* try with a user specified server */ + if (DEBUGLEVEL >= 11) { + char *s = NDR_PRINT_STRUCT_STRING(talloc_tos(), ads_struct, ads); + DEBUG(11,("ads_connect: entering\n")); + DEBUGADD(11,("%s\n", s)); + TALLOC_FREE(s); + } + if (ads->server.ldap_server && ads_try_connect(ads, ads->server.ldap_server)) { goto got_connection; @@ -401,7 +408,8 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) goto got_connection; } - return ADS_ERROR_NT(ntstatus); + status = ADS_ERROR_NT(ntstatus); + goto out; got_connection: @@ -438,12 +446,14 @@ got_connection: /* If the caller() requested no LDAP bind, then we are done */ if (ads->auth.flags & ADS_AUTH_NO_BIND) { - return ADS_SUCCESS; + status = ADS_SUCCESS; + goto out; } ads->ldap.mem_ctx = talloc_init("ads LDAP connection memory"); if (!ads->ldap.mem_ctx) { - return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + goto out; } /* Otherwise setup the TCP LDAP session */ @@ -451,7 +461,8 @@ got_connection: ads->ldap.ld = ldap_open_with_timeout(ads->config.ldap_server_name, LDAP_PORT, lp_ldap_timeout()); if (ads->ldap.ld == NULL) { - return ADS_ERROR(LDAP_OPERATIONS_ERROR); + status = ADS_ERROR(LDAP_OPERATIONS_ERROR); + goto out; } DEBUG(3,("Connected to LDAP server %s\n", ads->config.ldap_server_name)); @@ -466,27 +477,40 @@ got_connection: status = ADS_ERROR(smb_ldap_start_tls(ads->ldap.ld, version)); if (!ADS_ERR_OK(status)) { - return status; + goto out; } /* fill in the current time and offsets */ status = ads_current_time( ads ); if ( !ADS_ERR_OK(status) ) { - return status; + goto out; } /* Now do the bind */ if (ads->auth.flags & ADS_AUTH_ANON_BIND) { - return ADS_ERROR(ldap_simple_bind_s( ads->ldap.ld, NULL, NULL)); + status = ADS_ERROR(ldap_simple_bind_s(ads->ldap.ld, NULL, NULL)); + goto out; } if (ads->auth.flags & ADS_AUTH_SIMPLE_BIND) { - return ADS_ERROR(ldap_simple_bind_s( ads->ldap.ld, ads->auth.user_name, ads->auth.password)); + status = ADS_ERROR(ldap_simple_bind_s(ads->ldap.ld, ads->auth.user_name, ads->auth.password)); + goto out; + } + + status = ads_sasl_bind(ads); + + out: + if (DEBUGLEVEL >= 11) { + char *s = NDR_PRINT_STRUCT_STRING(talloc_tos(), ads_struct, ads); + DEBUG(11,("ads_connect: leaving with: %s\n", + ads_errstr(status))); + DEBUGADD(11,("%s\n", s)); + TALLOC_FREE(s); } - return ads_sasl_bind(ads); + return status; } /** -- cgit From 2762b9a97582b9b28fd5985ba8e3d0299126820e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 4 Feb 2008 20:57:35 +0100 Subject: Always pass a TALLOC_CTX to str_list_make and str_list_copy (This used to be commit e2c9fc4cf5f0ff725330fa44f53782db65fca37e) --- source3/libads/ldap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 7b0adc2fc3..ef6feb8ee0 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -664,7 +664,7 @@ static ADS_STATUS ads_do_paged_search_args(ADS_STRUCT *ads, else { /* This would be the utf8-encoded version...*/ /* if (!(search_attrs = ads_push_strvals(ctx, attrs))) */ - if (!(str_list_copy(&search_attrs, attrs))) { + if (!(str_list_copy(talloc_tos(), &search_attrs, attrs))) { rc = LDAP_NO_MEMORY; goto done; } @@ -974,7 +974,7 @@ ADS_STATUS ads_do_search_all_fn(ADS_STRUCT *ads, const char *bind_path, else { /* This would be the utf8-encoded version...*/ /* if (!(search_attrs = ads_push_strvals(ctx, attrs))) */ - if (!(str_list_copy(&search_attrs, attrs))) + if (!(str_list_copy(talloc_tos(), &search_attrs, attrs))) { DEBUG(1,("ads_do_search: str_list_copy() failed!")); rc = LDAP_NO_MEMORY; -- cgit From b361956942618ec2f7c2efc60cb190858adbc516 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 4 Feb 2008 21:05:41 +0100 Subject: str_list_free is not needed anymore (This used to be commit feddc1447d585fd108d22a36bccc576fa81197ef) --- source3/libads/ldap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index ef6feb8ee0..d6b9ba622b 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -801,7 +801,7 @@ done: } /* if/when we decide to utf8-encode attrs, take out this next line */ - str_list_free(&search_attrs); + TALLOC_FREE(search_attrs); return ADS_ERROR(rc); } @@ -998,7 +998,7 @@ ADS_STATUS ads_do_search_all_fn(ADS_STRUCT *ads, const char *bind_path, done: talloc_destroy(ctx); /* if/when we decide to utf8-encode attrs, take out this next line */ - str_list_free(&search_attrs); + TALLOC_FREE(search_attrs); return ADS_ERROR(rc); } /** -- cgit From 86843631a2bf533d869be693e1b049ce634c0f6e Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sun, 17 Feb 2008 01:57:20 +0100 Subject: Align our krb5 PAC decoding routines to the samba4 ones. (while keeping all the trans krb5 lib support) Guenther (This used to be commit c06e507737bb07ff995876e49341de3f60b0da35) --- source3/libads/authdata.c | 458 +++++++++++++++++++++++----------------------- 1 file changed, 224 insertions(+), 234 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c index 644f8515bc..1f90f76267 100644 --- a/source3/libads/authdata.c +++ b/source3/libads/authdata.c @@ -643,11 +643,11 @@ static bool pac_io_pac_data(const char *desc, PAC_DATA *data, return True; } -static NTSTATUS check_pac_checksum(TALLOC_CTX *mem_ctx, - DATA_BLOB pac_data, - PAC_SIGNATURE_DATA *sig, - krb5_context context, - krb5_keyblock *keyblock) +static krb5_error_code check_pac_checksum(TALLOC_CTX *mem_ctx, + DATA_BLOB pac_data, + struct PAC_SIGNATURE_DATA *sig, + krb5_context context, + krb5_keyblock *keyblock) { krb5_error_code ret; krb5_checksum cksum; @@ -663,299 +663,289 @@ static NTSTATUS check_pac_checksum(TALLOC_CTX *mem_ctx, #error UNKNOWN_KRB5_KEYUSAGE #endif - ret = smb_krb5_verify_checksum(context, - keyblock, - usage, + ret = smb_krb5_verify_checksum(context, + keyblock, + usage, &cksum, - pac_data.data, + pac_data.data, pac_data.length); if (ret) { - DEBUG(2,("check_pac_checksum: PAC Verification failed: %s (%d)\n", + DEBUG(2,("check_pac_checksum: PAC Verification failed: %s (%d)\n", error_message(ret), ret)); - return NT_STATUS_ACCESS_DENIED; + return ret; } - return NT_STATUS_OK; -} - -static NTSTATUS parse_pac_data(TALLOC_CTX *mem_ctx, DATA_BLOB *pac_data_blob, PAC_DATA *pac_data) -{ - prs_struct ps; - PAC_DATA *my_pac; - - if (!prs_init(&ps, pac_data_blob->length, mem_ctx, UNMARSHALL)) - return NT_STATUS_NO_MEMORY; - - if (!prs_copy_data_in(&ps, (char *)pac_data_blob->data, pac_data_blob->length)) - return NT_STATUS_INVALID_PARAMETER; - - prs_set_offset(&ps, 0); - - my_pac = TALLOC_ZERO_P(mem_ctx, PAC_DATA); - if (!pac_io_pac_data("pac data", my_pac, &ps, 0)) - return NT_STATUS_INVALID_PARAMETER; - - prs_mem_free(&ps); - - *pac_data = *my_pac; - - return NT_STATUS_OK; -} - -/* just for debugging, will be removed later - Guenther */ -char *pac_group_attr_string(uint32 attr) -{ - fstring name = ""; - - if (!attr) - return NULL; - - if (attr & SE_GROUP_MANDATORY) fstrcat(name, "SE_GROUP_MANDATORY "); - if (attr & SE_GROUP_ENABLED_BY_DEFAULT) fstrcat(name, "SE_GROUP_ENABLED_BY_DEFAULT "); - if (attr & SE_GROUP_ENABLED) fstrcat(name, "SE_GROUP_ENABLED "); - if (attr & SE_GROUP_OWNER) fstrcat(name, "SE_GROUP_OWNER "); - if (attr & SE_GROUP_USE_FOR_DENY_ONLY) fstrcat(name, "SE_GROUP_USE_FOR_DENY_ONLY "); - if (attr & SE_GROUP_LOGON_ID) fstrcat(name, "SE_GROUP_LOGON_ID "); - if (attr & SE_GROUP_RESOURCE) fstrcat(name, "SE_GROUP_RESOURCE "); - - return SMB_STRDUP(name); + return ret; } -/* just for debugging, will be removed later - Guenther */ -void dump_pac_logon_info(int lvl, PAC_LOGON_INFO *logon_info) -{ - DOM_SID dom_sid, res_group_dom_sid; - int i; - char *attr_string; - uint32 user_flgs = logon_info->info3.user_flgs; - - if (logon_info->info3.ptr_res_group_dom_sid) { - sid_copy(&res_group_dom_sid, &logon_info->res_group_dom_sid.sid); - } - sid_copy(&dom_sid, &logon_info->info3.dom_sid.sid); - - DEBUG(lvl,("The PAC:\n")); - - DEBUGADD(lvl,("\tUser Flags: 0x%x (%d)\n", user_flgs, user_flgs)); - if (user_flgs & NETLOGON_EXTRA_SIDS) - DEBUGADD(lvl,("\tUser Flags: NETLOGON_EXTRA_SIDS 0x%x (%d)\n", NETLOGON_EXTRA_SIDS, NETLOGON_EXTRA_SIDS)); - if (user_flgs & NETLOGON_RESOURCE_GROUPS) - DEBUGADD(lvl,("\tUser Flags: NETLOGON_RESOURCE_GROUPS 0x%x (%d)\n", NETLOGON_RESOURCE_GROUPS, NETLOGON_RESOURCE_GROUPS)); - DEBUGADD(lvl,("\tUser SID: %s-%d\n", sid_string_dbg(&dom_sid), - logon_info->info3.user_rid)); - DEBUGADD(lvl,("\tGroup SID: %s-%d\n", sid_string_dbg(&dom_sid), - logon_info->info3.group_rid)); - - DEBUGADD(lvl,("\tGroup Membership (Global and Universal Groups of own domain):\n")); - for (i = 0; i < logon_info->info3.num_groups; i++) { - attr_string = pac_group_attr_string(logon_info->info3.gids[i].attr); - DEBUGADD(lvl,("\t\t%d: sid: %s-%d\n\t\t attr: 0x%x == %s\n", - i, sid_string_dbg(&dom_sid), - logon_info->info3.gids[i].g_rid, - logon_info->info3.gids[i].attr, - attr_string)); - SAFE_FREE(attr_string); - } - - DEBUGADD(lvl,("\tGroup Membership (Domain Local Groups and Groups from Trusted Domains):\n")); - for (i = 0; i < logon_info->info3.num_other_sids; i++) { - attr_string = pac_group_attr_string(logon_info->info3.other_sids_attrib[i]); - DEBUGADD(lvl,("\t\t%d: sid: %s\n\t\t attr: 0x%x == %s\n", - i, sid_string_dbg( - &logon_info->info3.other_sids[i].sid), - logon_info->info3.other_sids_attrib[i], - attr_string)); - SAFE_FREE(attr_string); - } - - DEBUGADD(lvl,("\tGroup Membership (Resource Groups (SID History ?)):\n")); - for (i = 0; i < logon_info->info3.res_group_count; i++) { - attr_string = pac_group_attr_string(logon_info->res_groups.group_membership[i].attrs); - DEBUGADD(lvl,("\t\t%d: sid: %s-%d\n\t\t attr: 0x%x == %s\n", - i, sid_string_dbg(&res_group_dom_sid), - logon_info->res_groups.group_membership[i].rid, - logon_info->res_groups.group_membership[i].attrs, - attr_string)); - SAFE_FREE(attr_string); - } -} +/**************************************************************** +****************************************************************/ NTSTATUS decode_pac_data(TALLOC_CTX *mem_ctx, DATA_BLOB *pac_data_blob, - krb5_context context, + krb5_context context, krb5_keyblock *service_keyblock, krb5_const_principal client_principal, time_t tgs_authtime, - PAC_DATA **pac_data) - + struct PAC_DATA **pac_data_out) { - DATA_BLOB modified_pac_blob; - PAC_DATA *my_pac; - NTSTATUS nt_status; + NTSTATUS status; + enum ndr_err_code ndr_err; krb5_error_code ret; - PAC_SIGNATURE_DATA *srv_sig = NULL; - PAC_SIGNATURE_DATA *kdc_sig = NULL; - PAC_LOGON_NAME *logon_name = NULL; - PAC_LOGON_INFO *logon_info = NULL; - krb5_principal client_principal_pac = NULL; - NTTIME tgs_authtime_nttime; - int i, srv_sig_pos = 0, kdc_sig_pos = 0; - fstring username; + DATA_BLOB modified_pac_blob; - *pac_data = NULL; + NTTIME tgs_authtime_nttime; + krb5_principal client_principal_pac = NULL; + int i; - my_pac = talloc(mem_ctx, PAC_DATA); - if (!my_pac) { + struct PAC_SIGNATURE_DATA *srv_sig_ptr = NULL; + struct PAC_SIGNATURE_DATA *kdc_sig_ptr = NULL; + struct PAC_SIGNATURE_DATA *srv_sig_wipe = NULL; + struct PAC_SIGNATURE_DATA *kdc_sig_wipe = NULL; + struct PAC_LOGON_NAME *logon_name = NULL; + struct PAC_LOGON_INFO *logon_info = NULL; + struct PAC_DATA *pac_data = NULL; + struct PAC_DATA_RAW *pac_data_raw = NULL; + + DATA_BLOB *srv_sig_blob = NULL; + DATA_BLOB *kdc_sig_blob = NULL; + + *pac_data_out = NULL; + + pac_data = TALLOC_ZERO_P(mem_ctx, struct PAC_DATA); + pac_data_raw = TALLOC_ZERO_P(mem_ctx, struct PAC_DATA_RAW); + kdc_sig_wipe = TALLOC_ZERO_P(mem_ctx, struct PAC_SIGNATURE_DATA); + srv_sig_wipe = TALLOC_ZERO_P(mem_ctx, struct PAC_SIGNATURE_DATA); + if (!pac_data_raw || !pac_data || !kdc_sig_wipe || !srv_sig_wipe) { return NT_STATUS_NO_MEMORY; } - nt_status = parse_pac_data(mem_ctx, pac_data_blob, my_pac); - if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(0,("decode_pac_data: failed to parse PAC\n")); - return nt_status; + ndr_err = ndr_pull_struct_blob(pac_data_blob, pac_data, + pac_data, + (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + status = ndr_map_error2ntstatus(ndr_err); + DEBUG(0,("can't parse the PAC: %s\n", + nt_errstr(status))); + return status; } - modified_pac_blob = data_blob_talloc(mem_ctx, pac_data_blob->data, pac_data_blob->length); + if (pac_data->num_buffers < 4) { + /* we need logon_ingo, service_key and kdc_key */ + DEBUG(0,("less than 4 PAC buffers\n")); + return NT_STATUS_INVALID_PARAMETER; + } - if (my_pac->num_buffers < 4) { - nt_status = NT_STATUS_INVALID_PARAMETER; - goto out; + ndr_err = ndr_pull_struct_blob(pac_data_blob, pac_data_raw, + pac_data_raw, + (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA_RAW); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + status = ndr_map_error2ntstatus(ndr_err); + DEBUG(0,("can't parse the PAC: %s\n", + nt_errstr(status))); + return status; } - /* store signatures */ - for (i=0; i < my_pac->num_buffers; i++) { - - switch (my_pac->pac_buffer[i].type) { - - case PAC_TYPE_SERVER_CHECKSUM: - if (!my_pac->pac_buffer[i].ctr->pac.srv_cksum) { + if (pac_data_raw->num_buffers < 4) { + /* we need logon_ingo, service_key and kdc_key */ + DEBUG(0,("less than 4 PAC buffers\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + if (pac_data->num_buffers != pac_data_raw->num_buffers) { + /* we need logon_ingo, service_key and kdc_key */ + DEBUG(0,("misparse! PAC_DATA has %d buffers while PAC_DATA_RAW has %d\n", + pac_data->num_buffers, pac_data_raw->num_buffers)); + return NT_STATUS_INVALID_PARAMETER; + } + + for (i=0; i < pac_data->num_buffers; i++) { + if (pac_data->buffers[i].type != pac_data_raw->buffers[i].type) { + DEBUG(0,("misparse! PAC_DATA buffer %d has type %d while PAC_DATA_RAW has %d\n", + i, pac_data->buffers[i].type, pac_data->buffers[i].type)); + return NT_STATUS_INVALID_PARAMETER; + } + switch (pac_data->buffers[i].type) { + case PAC_TYPE_LOGON_INFO: + if (!pac_data->buffers[i].info) { break; } - - srv_sig = my_pac->pac_buffer[i].ctr->pac.srv_cksum; - - /* get position of signature buffer */ - srv_sig_pos = my_pac->pac_buffer[i].offset; - srv_sig_pos += sizeof(uint32); - + logon_info = pac_data->buffers[i].info->logon_info.info; break; - - case PAC_TYPE_PRIVSVR_CHECKSUM: - if (!my_pac->pac_buffer[i].ctr->pac.privsrv_cksum) { + case PAC_TYPE_SRV_CHECKSUM: + if (!pac_data->buffers[i].info) { break; } - - kdc_sig = my_pac->pac_buffer[i].ctr->pac.privsrv_cksum; - - /* get position of signature buffer */ - kdc_sig_pos = my_pac->pac_buffer[i].offset; - kdc_sig_pos += sizeof(uint32); - + srv_sig_ptr = &pac_data->buffers[i].info->srv_cksum; + srv_sig_blob = &pac_data_raw->buffers[i].info->remaining; break; - - case PAC_TYPE_LOGON_NAME: - if (!my_pac->pac_buffer[i].ctr->pac.logon_name) { + case PAC_TYPE_KDC_CHECKSUM: + if (!pac_data->buffers[i].info) { break; } - - logon_name = my_pac->pac_buffer[i].ctr->pac.logon_name; + kdc_sig_ptr = &pac_data->buffers[i].info->kdc_cksum; + kdc_sig_blob = &pac_data_raw->buffers[i].info->remaining; + break; + case PAC_TYPE_LOGON_NAME: + logon_name = &pac_data->buffers[i].info->logon_name; break; + default: + break; + } + } - case PAC_TYPE_LOGON_INFO: - if (!my_pac->pac_buffer[i].ctr->pac.logon_info) { - break; - } + if (!logon_info) { + DEBUG(0,("PAC no logon_info\n")); + return NT_STATUS_INVALID_PARAMETER; + } - logon_info = my_pac->pac_buffer[i].ctr->pac.logon_info; - break; - } + if (!logon_name) { + DEBUG(0,("PAC no logon_name\n")); + return NT_STATUS_INVALID_PARAMETER; + } + if (!srv_sig_ptr || !srv_sig_blob) { + DEBUG(0,("PAC no srv_key\n")); + return NT_STATUS_INVALID_PARAMETER; } - if (!srv_sig || !kdc_sig || !logon_name || !logon_info) { - nt_status = NT_STATUS_INVALID_PARAMETER; - goto out; + if (!kdc_sig_ptr || !kdc_sig_blob) { + DEBUG(0,("PAC no kdc_key\n")); + return NT_STATUS_INVALID_PARAMETER; } - /* zero PAC_SIGNATURE_DATA signature buffer */ - memset(&modified_pac_blob.data[srv_sig_pos], '\0', srv_sig->signature.buf_len); - memset(&modified_pac_blob.data[kdc_sig_pos], '\0', kdc_sig->signature.buf_len); + /* Find and zero out the signatures, as required by the signing algorithm */ - /* check server signature */ - nt_status = check_pac_checksum(mem_ctx, modified_pac_blob, srv_sig, context, service_keyblock); - if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(0,("decode_pac_data: failed to verify PAC server signature\n")); - goto out; + /* We find the data blobs above, now we parse them to get at the exact portion we should zero */ + ndr_err = ndr_pull_struct_blob(kdc_sig_blob, kdc_sig_wipe, + kdc_sig_wipe, + (ndr_pull_flags_fn_t)ndr_pull_PAC_SIGNATURE_DATA); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + status = ndr_map_error2ntstatus(ndr_err); + DEBUG(0,("can't parse the KDC signature: %s\n", + nt_errstr(status))); + return status; } - /* Convert to NT time, so as not to loose accuracy in comparison */ - unix_to_nt_time(&tgs_authtime_nttime, tgs_authtime); + ndr_err = ndr_pull_struct_blob(srv_sig_blob, srv_sig_wipe, + srv_sig_wipe, + (ndr_pull_flags_fn_t)ndr_pull_PAC_SIGNATURE_DATA); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + status = ndr_map_error2ntstatus(ndr_err); + DEBUG(0,("can't parse the SRV signature: %s\n", + nt_errstr(status))); + return status; + } - if (!nt_time_equals(&tgs_authtime_nttime, &logon_name->logon_time)) { - - DEBUG(2,("decode_pac_data: Logon time mismatch between ticket and PAC!\n")); - DEBUGADD(2, ("decode_pac_data: PAC: %s\n", - http_timestring(nt_time_to_unix(logon_name->logon_time)))); - DEBUGADD(2, ("decode_pac_data: Ticket: %s\n", - http_timestring(nt_time_to_unix(tgs_authtime_nttime)))); - - nt_status = NT_STATUS_ACCESS_DENIED; - goto out; + /* Now zero the decoded structure */ + memset(kdc_sig_wipe->signature.data, '\0', kdc_sig_wipe->signature.length); + memset(srv_sig_wipe->signature.data, '\0', srv_sig_wipe->signature.length); + + /* and reencode, back into the same place it came from */ + ndr_err = ndr_push_struct_blob(kdc_sig_blob, pac_data_raw, + kdc_sig_wipe, + (ndr_push_flags_fn_t)ndr_push_PAC_SIGNATURE_DATA); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + status = ndr_map_error2ntstatus(ndr_err); + DEBUG(0,("can't repack the KDC signature: %s\n", + nt_errstr(status))); + return status; + } + ndr_err = ndr_push_struct_blob(srv_sig_blob, pac_data_raw, + srv_sig_wipe, + (ndr_push_flags_fn_t)ndr_push_PAC_SIGNATURE_DATA); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + status = ndr_map_error2ntstatus(ndr_err); + DEBUG(0,("can't repack the SRV signature: %s\n", + nt_errstr(status))); + return status; } - if (!logon_name->len) { - DEBUG(2,("decode_pac_data: No Logon Name available\n")); - nt_status = NT_STATUS_INVALID_PARAMETER; - goto out; + /* push out the whole structure, but now with zero'ed signatures */ + ndr_err = ndr_push_struct_blob(&modified_pac_blob, pac_data_raw, + pac_data_raw, + (ndr_push_flags_fn_t)ndr_push_PAC_DATA_RAW); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + status = ndr_map_error2ntstatus(ndr_err); + DEBUG(0,("can't repack the RAW PAC: %s\n", + nt_errstr(status))); + return status; } - rpcstr_pull(username, logon_name->username, sizeof(username), logon_name->len, 0); - ret = smb_krb5_parse_name_norealm(context, username, &client_principal_pac); + /* verify by service_key */ + ret = check_pac_checksum(mem_ctx, + modified_pac_blob, srv_sig_ptr, + context, + service_keyblock); if (ret) { - DEBUG(2,("decode_pac_data: Could not parse name from incoming PAC: [%s]: %s\n", - username, error_message(ret))); - nt_status = NT_STATUS_INVALID_PARAMETER; - goto out; + DEBUG(1, ("PAC Decode: Failed to verify the service signature: %s\n", + error_message(ret))); + return NT_STATUS_ACCESS_DENIED; } - if (!smb_krb5_principal_compare_any_realm(context, client_principal, client_principal_pac)) { - DEBUG(2,("decode_pac_data: Name in PAC [%s] does not match principal name in ticket\n", - username)); - nt_status = NT_STATUS_ACCESS_DENIED; - goto out; + /* Convert to NT time, so as not to loose accuracy in comparison */ + unix_to_nt_time(&tgs_authtime_nttime, tgs_authtime); + + if (tgs_authtime_nttime != logon_name->logon_time) { + DEBUG(2, ("PAC Decode: Logon time mismatch between ticket and PAC!\n")); + DEBUG(2, ("PAC Decode: PAC: %s\n", nt_time_string(mem_ctx, logon_name->logon_time))); + DEBUG(2, ("PAC Decode: Ticket: %s\n", nt_time_string(mem_ctx, tgs_authtime_nttime))); + return NT_STATUS_ACCESS_DENIED; } - DEBUG(10,("Successfully validated Kerberos PAC\n")); + ret = smb_krb5_parse_name_norealm(context, logon_name->account_name, + &client_principal_pac); + if (ret) { + DEBUG(2, ("Could not parse name from incoming PAC: [%s]: %s\n", + logon_name->account_name, + error_message(ret))); + return NT_STATUS_INVALID_PARAMETER; + } - dump_pac_logon_info(10, logon_info); + if (!smb_krb5_principal_compare_any_realm(context, client_principal, client_principal_pac)) { + DEBUG(2, ("Name in PAC [%s] does not match principal name in ticket\n", + logon_name->account_name)); + krb5_free_principal(context, client_principal_pac); + return NT_STATUS_ACCESS_DENIED; + } - *pac_data = my_pac; + DEBUG(3,("Found account name from PAC: %s [%s]\n", + logon_info->info3.base.account_name.string, + logon_info->info3.base.full_name.string)); - nt_status = NT_STATUS_OK; + DEBUG(10,("Successfully validated Kerberos PAC\n")); -out: - if (client_principal_pac) { - krb5_free_principal(context, client_principal_pac); + if (DEBUGLEVEL >= 10) { + const char *s; + s = NDR_PRINT_STRUCT_STRING(mem_ctx, PAC_DATA, pac_data); + if (s) { + DEBUGADD(10,("%s\n", s)); + } } - return nt_status; + *pac_data_out = pac_data; + + return NT_STATUS_OK; } - PAC_LOGON_INFO *get_logon_info_from_pac(PAC_DATA *pac_data) +/**************************************************************** +****************************************************************/ + +struct PAC_LOGON_INFO *get_logon_info_from_pac(struct PAC_DATA *pac_data) { - PAC_LOGON_INFO *logon_info = NULL; int i; - + for (i=0; i < pac_data->num_buffers; i++) { - if (pac_data->pac_buffer[i].type != PAC_TYPE_LOGON_INFO) + if (pac_data->buffers[i].type != PAC_TYPE_LOGON_INFO) { continue; + } - logon_info = pac_data->pac_buffer[i].ctr->pac.logon_info; - break; + return pac_data->buffers[i].info->logon_info.info; } - return logon_info; + + return NULL; } /**************************************************************** @@ -971,12 +961,12 @@ NTSTATUS kerberos_return_pac(TALLOC_CTX *mem_ctx, bool request_pac, bool add_netbios_addr, time_t renewable_time, - PAC_DATA **pac_ret) + struct PAC_DATA **pac_ret) { krb5_error_code ret; NTSTATUS status = NT_STATUS_INVALID_PARAMETER; DATA_BLOB tkt, ap_rep, sesskey1, sesskey2; - PAC_DATA *pac_data = NULL; + struct PAC_DATA *pac_data = NULL; char *client_princ_out = NULL; const char *auth_princ = NULL; const char *local_service = NULL; @@ -1110,11 +1100,11 @@ static NTSTATUS kerberos_return_pac_logon_info(TALLOC_CTX *mem_ctx, bool request_pac, bool add_netbios_addr, time_t renewable_time, - PAC_LOGON_INFO **logon_info) + struct PAC_LOGON_INFO **logon_info) { NTSTATUS status; - PAC_DATA *pac_data = NULL; - PAC_LOGON_INFO *info = NULL; + struct PAC_DATA *pac_data = NULL; + struct PAC_LOGON_INFO *info = NULL; status = kerberos_return_pac(mem_ctx, name, @@ -1160,10 +1150,10 @@ NTSTATUS kerberos_return_info3_from_pac(TALLOC_CTX *mem_ctx, bool request_pac, bool add_netbios_addr, time_t renewable_time, - NET_USER_INFO_3 **info3) + struct netr_SamInfo3 **info3) { NTSTATUS status; - PAC_LOGON_INFO *logon_info = NULL; + struct PAC_LOGON_INFO *logon_info = NULL; status = kerberos_return_pac_logon_info(mem_ctx, name, -- cgit From 3ea40eda9435d91d9672fc054739cf1c926f2d2c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sun, 17 Feb 2008 01:57:57 +0100 Subject: Some more cleanup in authdata.c. Guenther (This used to be commit 5483f5fb44bb2138a1348c05845a2b8f3588697a) --- source3/libads/authdata.c | 628 +--------------------------------------------- 1 file changed, 7 insertions(+), 621 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c index 1f90f76267..79972875ac 100644 --- a/source3/libads/authdata.c +++ b/source3/libads/authdata.c @@ -1,23 +1,23 @@ -/* +/* Unix SMB/CIFS implementation. kerberos authorization data (PAC) utility library - Copyright (C) Jim McDonough 2003 + Copyright (C) Jim McDonough 2003 Copyright (C) Andrew Bartlett 2004-2005 Copyright (C) Andrew Tridgell 2001 Copyright (C) Luke Howard 2002-2003 Copyright (C) Stefan Metzmacher 2004-2005 Copyright (C) Guenther Deschner 2005,2007 - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -26,622 +26,8 @@ #ifdef HAVE_KRB5 -static bool pac_io_logon_name(const char *desc, PAC_LOGON_NAME *logon_name, - prs_struct *ps, int depth) -{ - if (NULL == logon_name) - return False; - - prs_debug(ps, depth, desc, "pac_io_logon_name"); - depth++; - - if (!smb_io_time("logon_time", &logon_name->logon_time, ps, depth)) - return False; - - if (!prs_uint16("len", ps, depth, &logon_name->len)) - return False; - - /* The following string is always in little endian 16 bit values, - copy as 8 bits to avoid endian reversal on big-endian machines. - len is the length in bytes. */ - - if (UNMARSHALLING(ps) && logon_name->len) { - logon_name->username = PRS_ALLOC_MEM(ps, uint8, logon_name->len); - if (!logon_name->username) { - DEBUG(3, ("No memory available\n")); - return False; - } - } - - if (!prs_uint8s(True, "name", ps, depth, logon_name->username, logon_name->len)) - return False; - - return True; -} - -#if 0 /* Unused (handled now in net_io_user_info3()) - Guenther */ -static bool pac_io_krb_sids(const char *desc, KRB_SID_AND_ATTRS *sid_and_attr, - prs_struct *ps, int depth) -{ - if (NULL == sid_and_attr) - return False; - - prs_debug(ps, depth, desc, "pac_io_krb_sids"); - depth++; - - if (UNMARSHALLING(ps)) { - sid_and_attr->sid = PRS_ALLOC_MEM(ps, DOM_SID2, 1); - if (!sid_and_attr->sid) { - DEBUG(3, ("No memory available\n")); - return False; - } - } - - if(!smb_io_dom_sid2("sid", sid_and_attr->sid, ps, depth)) - return False; - - return True; -} - - -static bool pac_io_krb_attrs(const char *desc, KRB_SID_AND_ATTRS *sid_and_attr, - prs_struct *ps, int depth) -{ - if (NULL == sid_and_attr) - return False; - - prs_debug(ps, depth, desc, "pac_io_krb_attrs"); - depth++; - - if (!prs_uint32("sid_ptr", ps, depth, &sid_and_attr->sid_ptr)) - return False; - if (!prs_uint32("attrs", ps, depth, &sid_and_attr->attrs)) - return False; - - return True; -} - -static bool pac_io_krb_sid_and_attr_array(const char *desc, - KRB_SID_AND_ATTR_ARRAY *array, - uint32 num, - prs_struct *ps, int depth) -{ - int i; - - if (NULL == array) - return False; - - prs_debug(ps, depth, desc, "pac_io_krb_sid_and_attr_array"); - depth++; - - - if (!prs_uint32("count", ps, depth, &array->count)) - return False; - - if (UNMARSHALLING(ps)) { - if (num) { - array->krb_sid_and_attrs = PRS_ALLOC_MEM(ps, KRB_SID_AND_ATTRS, num); - if (!array->krb_sid_and_attrs) { - DEBUG(3, ("No memory available\n")); - return False; - } - } else { - array->krb_sid_and_attrs = NULL; - } - } - - for (i=0; ikrb_sid_and_attrs[i], - ps, depth)) - return False; - - } - for (i=0; ikrb_sid_and_attrs[i], - ps, depth)) - return False; - - } - - return True; - -} -#endif - -static bool pac_io_group_membership(const char *desc, - GROUP_MEMBERSHIP *membership, - prs_struct *ps, int depth) -{ - if (NULL == membership) - return False; - - prs_debug(ps, depth, desc, "pac_io_group_membership"); - depth++; - - if (!prs_uint32("rid", ps, depth, &membership->rid)) - return False; - if (!prs_uint32("attrs", ps, depth, &membership->attrs)) - return False; - - return True; -} - - -static bool pac_io_group_membership_array(const char *desc, - GROUP_MEMBERSHIP_ARRAY *array, - uint32 num, - prs_struct *ps, int depth) -{ - int i; - - if (NULL == array) - return False; - - prs_debug(ps, depth, desc, "pac_io_group_membership_array"); - depth++; - - - if (!prs_uint32("count", ps, depth, &array->count)) - return False; - - if (UNMARSHALLING(ps)) { - if (num) { - array->group_membership = PRS_ALLOC_MEM(ps, GROUP_MEMBERSHIP, num); - if (!array->group_membership) { - DEBUG(3, ("No memory available\n")); - return False; - } - } else { - array->group_membership = NULL; - } - } - - for (i=0; igroup_membership[i], - ps, depth)) - return False; - - } - - return True; - -} - -#if 0 /* Unused, replaced using an expanded net_io_user_info3() now - Guenther */ -static bool pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info, - prs_struct *ps, int depth) -{ - uint32 garbage = 0, i; - - if (NULL == info) - return False; - - prs_debug(ps, depth, desc, "pac_io_pac_logon_info"); - depth++; - - if (!prs_align(ps)) - return False; - if (!prs_uint32("unknown", ps, depth, &garbage)) /* 00081001 */ - return False; - if (!prs_uint32("unknown", ps, depth, &garbage)) /* cccccccc */ - return False; - if (!prs_uint32("bufferlen", ps, depth, &garbage)) - return False; - if (!prs_uint32("bufferlenhi", ps, depth, &garbage)) /* 00000000 */ - return False; - - if (!prs_uint32("pointer", ps, depth, &garbage)) - return False; - - if (!prs_align(ps)) - return False; - if (!smb_io_time("logon_time", &info->logon_time, ps, depth)) - return False; - if (!smb_io_time("logoff_time", &info->logoff_time, ps, depth)) - return False; - if (!smb_io_time("kickoff_time", &info->kickoff_time, ps, depth)) - return False; - if (!smb_io_time("pass_last_set_time", &info->pass_last_set_time, - ps, depth)) - return False; - if (!smb_io_time("pass_can_change_time", &info->pass_can_change_time, - ps, depth)) - return False; - if (!smb_io_time("pass_must_change_time", &info->pass_must_change_time, - ps, depth)) - return False; - - if (!smb_io_unihdr("hdr_user_name", &info->hdr_user_name, ps, depth)) - return False; - if (!smb_io_unihdr("hdr_full_name", &info->hdr_full_name, ps, depth)) - return False; - if (!smb_io_unihdr("hdr_logon_script", &info->hdr_logon_script, - ps, depth)) - return False; - if (!smb_io_unihdr("hdr_profile_path", &info->hdr_profile_path, - ps, depth)) - return False; - if (!smb_io_unihdr("hdr_home_dir", &info->hdr_home_dir, ps, depth)) - return False; - if (!smb_io_unihdr("hdr_dir_drive", &info->hdr_dir_drive, ps, depth)) - return False; - - if (!prs_uint16("logon_count", ps, depth, &info->logon_count)) - return False; - if (!prs_uint16("bad_password_count", ps, depth, &info->bad_password_count)) - return False; - if (!prs_uint32("user_rid", ps, depth, &info->user_rid)) - return False; - if (!prs_uint32("group_rid", ps, depth, &info->group_rid)) - return False; - if (!prs_uint32("group_count", ps, depth, &info->group_count)) - return False; - /* I haven't seen this contain anything yet, but when it does - we will have to make sure we decode the contents in the middle - all the unistr2s ... */ - if (!prs_uint32("group_mem_ptr", ps, depth, - &info->group_membership_ptr)) - return False; - if (!prs_uint32("user_flags", ps, depth, &info->user_flags)) - return False; - - if (!prs_uint8s(False, "session_key", ps, depth, info->session_key, 16)) - return False; - - if (!smb_io_unihdr("hdr_dom_controller", - &info->hdr_dom_controller, ps, depth)) - return False; - if (!smb_io_unihdr("hdr_dom_name", &info->hdr_dom_name, ps, depth)) - return False; - - /* this should be followed, but just get ptr for now */ - if (!prs_uint32("ptr_dom_sid", ps, depth, &info->ptr_dom_sid)) - return False; - - if (!prs_uint8s(False, "lm_session_key", ps, depth, info->lm_session_key, 8)) - return False; - - if (!prs_uint32("acct_flags", ps, depth, &info->acct_flags)) - return False; - - for (i = 0; i < 7; i++) - { - if (!prs_uint32("unkown", ps, depth, &info->unknown[i])) /* unknown */ - return False; - } - - if (!prs_uint32("sid_count", ps, depth, &info->sid_count)) - return False; - if (!prs_uint32("ptr_extra_sids", ps, depth, &info->ptr_extra_sids)) - return False; - if (!prs_uint32("ptr_res_group_dom_sid", ps, depth, - &info->ptr_res_group_dom_sid)) - return False; - if (!prs_uint32("res_group_count", ps, depth, &info->res_group_count)) - return False; - if (!prs_uint32("ptr_res_groups", ps, depth, &info->ptr_res_groups)) - return False; - - if(!smb_io_unistr2("uni_user_name", &info->uni_user_name, - info->hdr_user_name.buffer, ps, depth)) - return False; - if(!smb_io_unistr2("uni_full_name", &info->uni_full_name, - info->hdr_full_name.buffer, ps, depth)) - return False; - if(!smb_io_unistr2("uni_logon_script", &info->uni_logon_script, - info->hdr_logon_script.buffer, ps, depth)) - return False; - if(!smb_io_unistr2("uni_profile_path", &info->uni_profile_path, - info->hdr_profile_path.buffer, ps, depth)) - return False; - if(!smb_io_unistr2("uni_home_dir", &info->uni_home_dir, - info->hdr_home_dir.buffer, ps, depth)) - return False; - if(!smb_io_unistr2("uni_dir_drive", &info->uni_dir_drive, - info->hdr_dir_drive.buffer, ps, depth)) - return False; - - if (info->group_membership_ptr) { - if (!pac_io_group_membership_array("group membership", - &info->groups, - info->group_count, - ps, depth)) - return False; - } - - - if(!smb_io_unistr2("uni_dom_controller", &info->uni_dom_controller, - info->hdr_dom_controller.buffer, ps, depth)) - return False; - if(!smb_io_unistr2("uni_dom_name", &info->uni_dom_name, - info->hdr_dom_name.buffer, ps, depth)) - return False; - - if(info->ptr_dom_sid) - if(!smb_io_dom_sid2("dom_sid", &info->dom_sid, ps, depth)) - return False; - - - if (info->sid_count && info->ptr_extra_sids) - if (!pac_io_krb_sid_and_attr_array("extra_sids", - &info->extra_sids, - info->sid_count, - ps, depth)) - return False; - - if (info->ptr_res_group_dom_sid) - if (!smb_io_dom_sid2("res_group_dom_sid", - &info->res_group_dom_sid, ps, depth)) - return False; - - if (info->ptr_res_groups) { - - if (!(info->user_flgs & LOGON_RESOURCE_GROUPS)) { - DEBUG(0,("user_flgs attribute does not have LOGON_RESOURCE_GROUPS\n")); - /* return False; */ - } - - if (!pac_io_group_membership_array("res group membership", - &info->res_groups, - info->res_group_count, - ps, depth)) - return False; - } - - return True; -} -#endif - -static bool pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info, - prs_struct *ps, int depth) -{ - uint32 garbage = 0; - bool kerb_validation_info = True; - - if (NULL == info) - return False; - - prs_debug(ps, depth, desc, "pac_io_pac_logon_info"); - depth++; - - if (!prs_align(ps)) - return False; - if (!prs_uint32("unknown", ps, depth, &garbage)) /* 00081001 */ - return False; - if (!prs_uint32("unknown", ps, depth, &garbage)) /* cccccccc */ - return False; - if (!prs_uint32("bufferlen", ps, depth, &garbage)) - return False; - if (!prs_uint32("bufferlenhi", ps, depth, &garbage)) /* 00000000 */ - return False; - - if(!net_io_user_info3("", &info->info3, ps, depth, 3, kerb_validation_info)) - return False; - - if (info->info3.ptr_res_group_dom_sid) { - if (!smb_io_dom_sid2("res_group_dom_sid", - &info->res_group_dom_sid, ps, depth)) - return False; - } - - if (info->info3.ptr_res_groups) { - - if (!(info->info3.user_flgs & NETLOGON_RESOURCE_GROUPS)) { - DEBUG(0,("user_flgs attribute does not have NETLOGON_RESOURCE_GROUPS\n")); - /* return False; */ - } - - if (!pac_io_group_membership_array("res group membership", - &info->res_groups, - info->info3.res_group_count, - ps, depth)) - return False; - } - - return True; -} - - - -static bool pac_io_pac_signature_data(const char *desc, - PAC_SIGNATURE_DATA *data, uint32 length, - prs_struct *ps, int depth) -{ - uint32 siglen = 0; - - prs_debug(ps, depth, desc, "pac_io_pac_signature_data"); - depth++; - - if (data == NULL) - return False; - - if (!prs_align(ps)) - return False; - if (!prs_uint32("type", ps, depth, &data->type)) - return False; - - if ( length > sizeof(uint32) ) - siglen = length - sizeof(uint32); - - if (UNMARSHALLING(ps) && length) { - if (siglen) { - data->signature.buffer = PRS_ALLOC_MEM(ps, uint8, siglen); - if (!data->signature.buffer) { - DEBUG(3, ("No memory available\n")); - return False; - } - } else { - data->signature.buffer = NULL; - } - } - - data->signature.buf_len = siglen; - - if (!prs_uint8s(False, "signature", ps, depth, data->signature.buffer, data->signature.buf_len)) - return False; - - - return True; -} - -static bool pac_io_pac_info_hdr_ctr(const char *desc, PAC_BUFFER *hdr, - prs_struct *ps, int depth) -{ - if (NULL == hdr) - return False; - - prs_debug(ps, depth, desc, "pac_io_pac_info_hdr_ctr"); - depth++; - - if (!prs_align(ps)) - return False; - - if (hdr->offset != prs_offset(ps)) { - DEBUG(5,("offset in header(x%x) and data(x%x) do not match, correcting\n", - hdr->offset, prs_offset(ps))); - prs_set_offset(ps, hdr->offset); - } - - if (UNMARSHALLING(ps) && hdr->size > 0) { - hdr->ctr = PRS_ALLOC_MEM(ps, PAC_INFO_CTR, 1); - if (!hdr->ctr) { - DEBUG(3, ("No memory available\n")); - return False; - } - } - - switch(hdr->type) { - case PAC_TYPE_LOGON_INFO: - DEBUG(5, ("PAC_TYPE_LOGON_INFO\n")); - if (UNMARSHALLING(ps)) - hdr->ctr->pac.logon_info = PRS_ALLOC_MEM(ps, PAC_LOGON_INFO, 1); - if (!hdr->ctr->pac.logon_info) { - DEBUG(3, ("No memory available\n")); - return False; - } - if (!pac_io_pac_logon_info(desc, hdr->ctr->pac.logon_info, - ps, depth)) - return False; - break; - - case PAC_TYPE_SERVER_CHECKSUM: - DEBUG(5, ("PAC_TYPE_SERVER_CHECKSUM\n")); - if (UNMARSHALLING(ps)) - hdr->ctr->pac.srv_cksum = PRS_ALLOC_MEM(ps, PAC_SIGNATURE_DATA, 1); - if (!hdr->ctr->pac.srv_cksum) { - DEBUG(3, ("No memory available\n")); - return False; - } - if (!pac_io_pac_signature_data(desc, hdr->ctr->pac.srv_cksum, - hdr->size, ps, depth)) - return False; - break; - - case PAC_TYPE_PRIVSVR_CHECKSUM: - DEBUG(5, ("PAC_TYPE_PRIVSVR_CHECKSUM\n")); - if (UNMARSHALLING(ps)) - hdr->ctr->pac.privsrv_cksum = PRS_ALLOC_MEM(ps, PAC_SIGNATURE_DATA, 1); - if (!hdr->ctr->pac.privsrv_cksum) { - DEBUG(3, ("No memory available\n")); - return False; - } - if (!pac_io_pac_signature_data(desc, - hdr->ctr->pac.privsrv_cksum, - hdr->size, ps, depth)) - return False; - break; - - case PAC_TYPE_LOGON_NAME: - DEBUG(5, ("PAC_TYPE_LOGON_NAME\n")); - if (UNMARSHALLING(ps)) - hdr->ctr->pac.logon_name = PRS_ALLOC_MEM(ps, PAC_LOGON_NAME, 1); - if (!hdr->ctr->pac.logon_name) { - DEBUG(3, ("No memory available\n")); - return False; - } - if (!pac_io_logon_name(desc, hdr->ctr->pac.logon_name, - ps, depth)) - return False; - break; - - default: - /* dont' know, so we need to skip it */ - DEBUG(3, ("unknown PAC type %d\n", hdr->type)); - prs_set_offset(ps, prs_offset(ps) + hdr->size); - } - -#if 0 - /* obscure pad */ - if (!prs_uint32("pad", ps, depth, &hdr->pad)) - return False; -#endif - return True; -} - -static bool pac_io_pac_info_hdr(const char *desc, PAC_BUFFER *hdr, - prs_struct *ps, int depth) -{ - if (NULL == hdr) - return False; - - prs_debug(ps, depth, desc, "pac_io_pac_info_hdr"); - depth++; - - if (!prs_align(ps)) - return False; - if (!prs_uint32("type", ps, depth, &hdr->type)) - return False; - if (!prs_uint32("size", ps, depth, &hdr->size)) - return False; - if (!prs_uint32("offset", ps, depth, &hdr->offset)) - return False; - if (!prs_uint32("offsethi", ps, depth, &hdr->offsethi)) - return False; - - return True; -} - -static bool pac_io_pac_data(const char *desc, PAC_DATA *data, - prs_struct *ps, int depth) -{ - int i; - - if (NULL == data) - return False; - - prs_debug(ps, depth, desc, "pac_io_pac_data"); - depth++; - - if (!prs_align(ps)) - return False; - if (!prs_uint32("num_buffers", ps, depth, &data->num_buffers)) - return False; - if (!prs_uint32("version", ps, depth, &data->version)) - return False; - - if (UNMARSHALLING(ps) && data->num_buffers > 0) { - if ((data->pac_buffer = PRS_ALLOC_MEM(ps, PAC_BUFFER, data->num_buffers)) == NULL) { - return False; - } - } - - for (i=0; inum_buffers; i++) { - if (!pac_io_pac_info_hdr(desc, &data->pac_buffer[i], ps, - depth)) - return False; - } - - for (i=0; inum_buffers; i++) { - if (!pac_io_pac_info_hdr_ctr(desc, &data->pac_buffer[i], - ps, depth)) - return False; - } - - return True; -} +/**************************************************************** +****************************************************************/ static krb5_error_code check_pac_checksum(TALLOC_CTX *mem_ctx, DATA_BLOB pac_data, -- cgit From 965774fa8f78a6b0f3306d356fd0d17a2a8943df Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sun, 17 Feb 2008 02:01:30 +0100 Subject: Fix some more callers of PAC_DATA. Guenther (This used to be commit ea609d1b0e82d7c366dd73013228003136264b64) --- source3/libads/kerberos_verify.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 5ce7aa6b45..f112dd34e3 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -309,7 +309,7 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, time_t time_offset, const DATA_BLOB *ticket, char **principal, - PAC_DATA **pac_data, + struct PAC_DATA **pac_data, DATA_BLOB *ap_rep, DATA_BLOB *session_key, bool use_replay_cache) -- cgit From 317639287886181edf08ccecad1b324e4cc55d0b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 25 Feb 2008 15:24:49 +0100 Subject: Fix some warnings warning: ignoring return value of 'asprintf', declared with attribute warn_unused_result (This used to be commit ad37b7b0aee265a3e4d8b7552610f4b9a105434d) --- source3/libads/kerberos.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index d47e8a3ff1..b37b9a500f 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -407,8 +407,8 @@ static char *kerberos_secrets_fetch_salting_principal(const char *service, int e char *key = NULL; char *ret = NULL; - asprintf(&key, "%s/%s/enctype=%d", SECRETS_SALTING_PRINCIPAL, service, enctype); - if (!key) { + if (asprintf(&key, "%s/%s/enctype=%d", + SECRETS_SALTING_PRINCIPAL, service, enctype) == -1) { return NULL; } ret = (char *)secrets_fetch(key, NULL); @@ -438,7 +438,10 @@ static char* des_salt_key( void ) { char *key; - asprintf(&key, "%s/DES/%s", SECRETS_SALTING_PRINCIPAL, lp_realm()); + if (asprintf(&key, "%s/DES/%s", SECRETS_SALTING_PRINCIPAL, + lp_realm()) == -1) { + return NULL; + } return key; } @@ -609,9 +612,13 @@ bool kerberos_secrets_store_salting_principal(const char *service, return False; } if (strchr_m(service, '@')) { - asprintf(&princ_s, "%s", service); + if (asprintf(&princ_s, "%s", service) == -1) { + goto out; + } } else { - asprintf(&princ_s, "%s@%s", service, lp_realm()); + if (asprintf(&princ_s, "%s@%s", service, lp_realm()) == -1) { + goto out; + } } if (smb_krb5_parse_name(context, princ_s, &princ) != 0) { @@ -622,8 +629,9 @@ bool kerberos_secrets_store_salting_principal(const char *service, goto out; } - asprintf(&key, "%s/%s/enctype=%d", SECRETS_SALTING_PRINCIPAL, unparsed_name, enctype); - if (!key) { + if (asprintf(&key, "%s/%s/enctype=%d", + SECRETS_SALTING_PRINCIPAL, unparsed_name, enctype) + == -1) { goto out; } -- cgit From 7269a504fdd06fbbe24c2df8e084b41382d71269 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 27 Feb 2008 19:38:48 +0100 Subject: Add my copyright. Guenther (This used to be commit d078a8757182d84dfd3307a2e1b751cf173aaa97) --- source3/libads/authdata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c index 79972875ac..0bde3e6984 100644 --- a/source3/libads/authdata.c +++ b/source3/libads/authdata.c @@ -6,7 +6,7 @@ Copyright (C) Andrew Tridgell 2001 Copyright (C) Luke Howard 2002-2003 Copyright (C) Stefan Metzmacher 2004-2005 - Copyright (C) Guenther Deschner 2005,2007 + Copyright (C) Guenther Deschner 2005,2007,2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -- cgit From 87805819f108f0d2a7376ca78952a6e6a36bc6db Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 8 Mar 2008 23:48:12 +0100 Subject: Fix Coverity ID 551 Correctly return if we can't create the temporary krb5.conf Jeremy, please check! (This used to be commit c2401811aa3d02a9e27969687b9ea035407000c3) --- source3/libads/kerberos.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index b37b9a500f..ee25fb5551 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -894,6 +894,8 @@ bool create_local_private_krb5_conf_for_domain(const char *realm, DEBUG(0,("create_local_private_krb5_conf_for_domain: smb_mkstemp failed," " for file %s. Errno %s\n", tmpname, strerror(errno) )); + TALLOC_FREE(dname); + return false; } if (fchmod(fd, 0644)==-1) { -- cgit From 1ebfc66b2c145289d1e1314e8415d9e3c6f405ae Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 10 Mar 2008 21:08:29 +0100 Subject: Use a separate tdb for mutexes Another preparation to convert secrets.c to dbwrap: The dbwrap API does not provide a sane tdb_lock_with_timeout abstraction. In the clustered case the DC mutex is needed per-node anyway, so it is perfectly fine to use a local mutex only. (This used to be commit f94a63cd8f94490780ad9331da229c0bcb2ca5d6) --- source3/libads/kerberos_verify.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index f112dd34e3..6b482ecd20 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -330,8 +330,8 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, krb5_const_principal client_principal = NULL; char *host_princ_s = NULL; bool auth_ok = False; - bool got_replay_mutex = False; bool got_auth_data = False; + struct named_mutex *mutex = NULL; ZERO_STRUCT(packet); ZERO_STRUCT(auth_data); @@ -395,15 +395,15 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, locking in the MIT krb5 code surrounding the replay cache... */ - if (!grab_server_mutex("replay cache mutex")) { + mutex = grab_named_mutex(talloc_tos(), "replay cache mutex", + 10); + if (mutex == NULL) { DEBUG(1,("ads_verify_ticket: unable to protect " "replay cache with mutex.\n")); ret = KRB5_CC_IO; goto out; } - got_replay_mutex = True; - /* JRA. We must set the rcache here. This will prevent replay attacks. */ @@ -443,8 +443,7 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, } if ( use_replay_cache ) { - release_server_mutex(); - got_replay_mutex = False; + TALLOC_FREE(mutex); #if 0 /* Heimdal leaks here, if we fix the leak, MIT crashes */ if (rcache) { @@ -539,9 +538,7 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, out: - if (got_replay_mutex) { - release_server_mutex(); - } + TALLOC_FREE(mutex); if (!NT_STATUS_IS_OK(sret)) { data_blob_free(&auth_data); -- cgit From e06aa46b9fab1e107fea8f6453fb13deffa91e96 Mon Sep 17 00:00:00 2001 From: Marc VanHeyningen Date: Fri, 14 Mar 2008 14:26:28 -0800 Subject: Coverity fixes (This used to be commit 3fc85d22590550f0539215d020e4411bf5b14363) --- source3/libads/kerberos.c | 6 ++++-- source3/libads/krb5_setpw.c | 17 ++++++++++++++--- source3/libads/ldap.c | 5 ++++- 3 files changed, 22 insertions(+), 6 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index ee25fb5551..66f203b12d 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -606,9 +606,11 @@ bool kerberos_secrets_store_salting_principal(const char *service, krb5_principal princ = NULL; char *princ_s = NULL; char *unparsed_name = NULL; + krb5_error_code code; - krb5_init_context(&context); - if (!context) { + if (((code = krb5_init_context(&context)) != 0) || (context == NULL)) { + DEBUG(5, ("kerberos_secrets_store_salting_pricipal: kdb5_init_context failed: %s\n", + error_message(code))); return False; } if (strchr_m(service, '@')) { diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 852251a476..719f3bd3ec 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -438,10 +438,21 @@ static ADS_STATUS do_krb5_kpasswd_request(krb5_context context, return ADS_ERROR_SYSTEM(rc); } addr_len = sizeof(remote_addr); - getpeername(sock, (struct sockaddr *)&remote_addr, &addr_len); + if (getpeername(sock, (struct sockaddr *)&remote_addr, &addr_len) != 0) { + close(sock); + SAFE_FREE(ap_req.data); + krb5_auth_con_free(context, auth_context); + DEBUG(1,("getpeername() failed (%s)\n", error_message(errno))); + return ADS_ERROR_SYSTEM(errno); + } addr_len = sizeof(local_addr); - getsockname(sock, (struct sockaddr *)&local_addr, &addr_len); - + if (getsockname(sock, (struct sockaddr *)&local_addr, &addr_len) != 0) { + close(sock); + SAFE_FREE(ap_req.data); + krb5_auth_con_free(context, auth_context); + DEBUG(1,("getsockname() failed (%s)\n", error_message(errno))); + return ADS_ERROR_SYSTEM(errno); + } if (!setup_kaddr(&remote_kaddr, &remote_addr) || !setup_kaddr(&local_kaddr, &local_addr)) { DEBUG(1,("do_krb5_kpasswd_request: " diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index d6b9ba622b..9ec06e5a1d 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -588,7 +588,10 @@ static char **ads_push_strvals(TALLOC_CTX *ctx, const char **in_vals) if (!values) return NULL; for (i=0; in_vals[i]; i++) { - push_utf8_talloc(ctx, &values[i], in_vals[i]); + if (push_utf8_talloc(ctx, &values[i], in_vals[i]) == (size_t) -1) { + TALLOC_FREE(values); + return NULL; + } } return values; } -- cgit From 561fb9daa4fa361e5db57bcc64f3a3114c6623fa Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 23 Mar 2008 19:26:35 +0100 Subject: Fix Coverity ID 487 (This used to be commit 22cee9c1afbc33b4920b72bc81569d79642172af) --- source3/libads/ldap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 9ec06e5a1d..00d36b7edc 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -3413,6 +3413,7 @@ ADS_STATUS ads_find_samaccount(ADS_STRUCT *ads, filter = talloc_asprintf(mem_ctx, "(&(objectclass=user)(sAMAccountName=%s))", samaccountname); if (filter == NULL) { + status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY); goto out; } -- cgit From 1b26a7ea6d00e159b43deec906e6b3971617088a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 23 Mar 2008 19:30:47 +0100 Subject: Fix Coverity ID 488 "status" was used uninitialized on success -- metze, please check (This used to be commit a0859529c853ffb756b1deee946923b6fff6136e) --- source3/libads/sasl.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 798d0b4365..55bc16a1be 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -597,6 +597,8 @@ static ADS_STATUS ads_sasl_spnego_gsskrb5_bind(ADS_STRUCT *ads, const gss_name_t context_handle = GSS_C_NO_CONTEXT; } + status = ADS_SUCCESS; + failed: if (context_handle != GSS_C_NO_CONTEXT) gss_delete_sec_context(&minor_status, &context_handle, GSS_C_NO_BUFFER); -- cgit From 33a3766f033a25b0eb47a3537101d1141d26db3f Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 28 Mar 2008 16:33:54 +0100 Subject: Add ads_check_ou_dn(). Guenther (This used to be commit 380e9d26db5341d10807ccbfb413d0f53d3ffc71) --- source3/libads/ldap.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 00d36b7edc..a9eff48b3e 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -22,6 +22,7 @@ */ #include "includes.h" +#include "lib/ldb/include/includes.h" #ifdef HAVE_LDAP @@ -3551,4 +3552,50 @@ const char *ads_get_extended_right_name_by_guid(ADS_STRUCT *ads, } +/** + * verify or build and verify an account ou + * @param mem_ctx Pointer to talloc context + * @param ads connection to ads server + * @param account_ou + * @return status of search + **/ + +ADS_STATUS ads_check_ou_dn(TALLOC_CTX *mem_ctx, + ADS_STRUCT *ads, + const char *account_ou) +{ + struct ldb_dn *name_dn = NULL; + const char *name = NULL; + char *ou_string = NULL; + + name_dn = ldb_dn_explode(mem_ctx, account_ou); + if (name_dn) { + return ADS_SUCCESS; + } + + ou_string = ads_ou_string(ads, account_ou); + if (!ou_string) { + return ADS_ERROR_LDAP(LDAP_INVALID_DN_SYNTAX); + } + + name = talloc_asprintf(mem_ctx, "%s,%s", ou_string, + ads->config.bind_path); + SAFE_FREE(ou_string); + if (!name) { + return ADS_ERROR_LDAP(LDAP_NO_MEMORY); + } + + name_dn = ldb_dn_explode(mem_ctx, name); + if (!name_dn) { + return ADS_ERROR_LDAP(LDAP_INVALID_DN_SYNTAX); + } + + account_ou = talloc_strdup(mem_ctx, name); + if (!account_ou) { + return ADS_ERROR_LDAP(LDAP_NO_MEMORY); + } + + return ADS_SUCCESS; +} + #endif -- cgit From a8124367b4fcfea165569e4ce1e3401deacb0142 Mon Sep 17 00:00:00 2001 From: Karolin Seeger Date: Wed, 9 Apr 2008 16:14:04 +0200 Subject: Fix typos. Karolin (This used to be commit 6cee34703503fbf3629057345fe221b866560648) --- source3/libads/kerberos_verify.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 6b482ecd20..65c13a849f 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -127,7 +127,7 @@ static bool ads_keytab_verify_ticket(krb5_context context, /* workaround for MIT: * as krb5_ktfile_get_entry will explicitly * close the krb5_keytab as soon as krb5_rd_req - * has sucessfully decrypted the ticket but the + * has sucsessfully decrypted the ticket but the * ticket is not valid yet (due to clockskew) * there is no point in querying more keytab * entries - Guenther */ -- cgit From 8d7c7c674a2c763ccb95bd3ba63a7c9479cfc993 Mon Sep 17 00:00:00 2001 From: Karolin Seeger Date: Thu, 10 Apr 2008 08:38:26 +0200 Subject: Fix typo. Karolin (This used to be commit 42fbbeb1caf93e4e17bb62f31ff90a853bd169fb) --- source3/libads/kerberos_verify.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 65c13a849f..a4d7a8e680 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -127,7 +127,7 @@ static bool ads_keytab_verify_ticket(krb5_context context, /* workaround for MIT: * as krb5_ktfile_get_entry will explicitly * close the krb5_keytab as soon as krb5_rd_req - * has sucsessfully decrypted the ticket but the + * has successfully decrypted the ticket but the * ticket is not valid yet (due to clockskew) * there is no point in querying more keytab * entries - Guenther */ -- cgit From 2a2188591b5ed922d09dc723adcf10f8b8f5e5a0 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 19 Apr 2008 21:56:43 +0200 Subject: Add "desthost" to rpc_pipe_client This reduces the dependency on cli_state (This used to be commit 783afab9c891dd7bcb78895b2a639b6f3a0edf5b) --- source3/libads/ldap_printer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index 05fbc071d8..e2396ce4cf 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -288,7 +288,7 @@ WERROR get_remote_printer_publishing_data(struct rpc_pipe_client *cli, uint32 i; POLICY_HND pol; - asprintf(&servername, "\\\\%s", cli->cli->desthost); + asprintf(&servername, "\\\\%s", cli->desthost); asprintf(&printername, "%s\\%s", servername, printer); if (!servername || !printername) { DEBUG(3, ("Insufficient memory\n")); -- cgit From 4c857010e7113d99028cf8d7fac5e5b95c400fb3 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 19 Apr 2008 22:05:13 +0200 Subject: Fix two "ignoring asprintf result" warnings (This used to be commit 1d261e78b38e8080ca7122037d33c8ef913a4558) --- source3/libads/ldap_printer.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index e2396ce4cf..440f979781 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -288,9 +288,8 @@ WERROR get_remote_printer_publishing_data(struct rpc_pipe_client *cli, uint32 i; POLICY_HND pol; - asprintf(&servername, "\\\\%s", cli->desthost); - asprintf(&printername, "%s\\%s", servername, printer); - if (!servername || !printername) { + if ((asprintf(&servername, "\\\\%s", cli->desthost) == -1) + || (asprintf(&printername, "%s\\%s", servername, printer) == -1)) { DEBUG(3, ("Insufficient memory\n")); return WERR_NOMEM; } -- cgit From cf2442bdcb68d75582da98ba15da8928c37fb058 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Apr 2008 00:01:52 +0200 Subject: Use rpc_pipe_client->user_name instead of rpc_pipe_client->cli->user_name Also make sure that rpc_pipe_client->user_name is always talloced. (This used to be commit 3f6c5b99664a75a6f490ee3b6980b89cacf7f579) --- source3/libads/ldap_printer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index 440f979781..6682ec24d0 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -296,7 +296,7 @@ WERROR get_remote_printer_publishing_data(struct rpc_pipe_client *cli, result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS, - servername, cli->cli->user_name, &pol); + servername, cli->user_name, &pol); if (!W_ERROR_IS_OK(result)) { DEBUG(3, ("Unable to open printer %s, error is %s.\n", printername, dos_errstr(result))); -- cgit From ba98dd4989db16028a2690d382ab178524ce765b Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 21 Apr 2008 19:26:32 +0200 Subject: libads: Use libnbt for CLDAP reply parsing. Guenther (This used to be commit 751f3064a508341c0ebae45e8de9f5311d915d70) --- source3/libads/cldap.c | 105 ++++++------------------------------------------- source3/libads/ldap.c | 24 +++++------ 2 files changed, 24 insertions(+), 105 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/cldap.c b/source3/libads/cldap.c index 39e736f28a..6068ca4faf 100644 --- a/source3/libads/cldap.c +++ b/source3/libads/cldap.c @@ -20,72 +20,6 @@ #include "includes.h" -/* - These seem to be strings as described in RFC1035 4.1.4 and can be: - - - a sequence of labels ending in a zero octet - - a pointer - - a sequence of labels ending with a pointer - - A label is a byte where the first two bits must be zero and the remaining - bits represent the length of the label followed by the label itself. - Therefore, the length of a label is at max 64 bytes. Under RFC1035, a - sequence of labels cannot exceed 255 bytes. - - A pointer consists of a 14 bit offset from the beginning of the data. - - struct ptr { - unsigned ident:2; // must be 11 - unsigned offset:14; // from the beginning of data - }; - - This is used as a method to compress the packet by eliminated duplicate - domain components. Since a UDP packet should probably be < 512 bytes and a - DNS name can be up to 255 bytes, this actually makes a lot of sense. -*/ -static unsigned pull_netlogon_string(char *ret, const char *ptr, - const char *data) -{ - char *pret = ret; - int followed_ptr = 0; - unsigned ret_len = 0; - - memset(pret, 0, MAX_DNS_LABEL); - do { - if ((*ptr & 0xc0) == 0xc0) { - uint16 len; - - if (!followed_ptr) { - ret_len += 2; - followed_ptr = 1; - } - len = ((ptr[0] & 0x3f) << 8) | ptr[1]; - ptr = data + len; - } else if (*ptr) { - uint8 len = (uint8)*(ptr++); - - if ((pret - ret + len + 1) >= MAX_DNS_LABEL) { - DEBUG(1,("DC returning too long DNS name\n")); - return 0; - } - - if (pret != ret) { - *pret = '.'; - pret++; - } - memcpy(pret, ptr, len); - pret += len; - ptr += len; - - if (!followed_ptr) { - ret_len += (len + 1); - } - } - } while (*ptr); - - return followed_ptr ? ret_len : ret_len + 1; -} - /* do a cldap netlogon query */ @@ -182,7 +116,7 @@ static void gotalarm_sig(void) /* receive a cldap netlogon reply */ -static int recv_cldap_netlogon(int sock, struct cldap_netlogon_reply *reply) +static int recv_cldap_netlogon(int sock, struct nbt_cldap_netlogon_5 *reply) { int ret; ASN1_DATA data; @@ -193,7 +127,8 @@ static int recv_cldap_netlogon(int sock, struct cldap_netlogon_reply *reply) 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); - char *p; + union nbt_cldap_netlogon p; + enum ndr_err_code ndr_err; blob = data_blob(NULL, 8192); if (blob.data == NULL) { @@ -247,33 +182,17 @@ static int recv_cldap_netlogon(int sock, struct cldap_netlogon_reply *reply) return -1; } - p = (char *)os3.data; - - reply->type = IVAL(p, 0); p += 4; - reply->flags = IVAL(p, 0); p += 4; - - memcpy(&reply->guid.info, p, UUID_FLAT_SIZE); - p += UUID_FLAT_SIZE; - - p += pull_netlogon_string(reply->forest, p, (const char *)os3.data); - p += pull_netlogon_string(reply->domain, p, (const char *)os3.data); - p += pull_netlogon_string(reply->hostname, p, (const char *)os3.data); - p += pull_netlogon_string(reply->netbios_domain, p, (const char *)os3.data); - p += pull_netlogon_string(reply->netbios_hostname, p, (const char *)os3.data); - p += pull_netlogon_string(reply->unk, p, (const char *)os3.data); - - if (reply->type == SAMLOGON_AD_R) { - p += pull_netlogon_string(reply->user_name, p, (const char *)os3.data); - } else { - *reply->user_name = 0; + ndr_err = ndr_pull_union_blob_all(&os3, talloc_tos(), &p, 5, + (ndr_pull_flags_fn_t)ndr_pull_nbt_cldap_netlogon); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return -1; } - p += pull_netlogon_string(reply->server_site_name, p, (const char *)os3.data); - p += pull_netlogon_string(reply->client_site_name, p, (const char *)os3.data); + *reply = p.logon5; - reply->version = IVAL(p, 0); - reply->lmnt_token = SVAL(p, 4); - reply->lm20_token = SVAL(p, 6); + if (DEBUGLEVEL >= 10) { + NDR_PRINT_UNION_DEBUG(nbt_cldap_netlogon, 5, &p); + } data_blob_free(&os1); data_blob_free(&os2); @@ -289,7 +208,7 @@ static int recv_cldap_netlogon(int sock, struct cldap_netlogon_reply *reply) do a cldap netlogon query. Always 389/udp *******************************************************************/ -bool ads_cldap_netlogon(const char *server, const char *realm, struct cldap_netlogon_reply *reply) +bool ads_cldap_netlogon(const char *server, const char *realm, struct nbt_cldap_netlogon_5 *reply) { int sock; int ret; diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index a9eff48b3e..b4a977056e 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -176,7 +176,7 @@ bool ads_closest_dc(ADS_STRUCT *ads) bool ads_try_connect(ADS_STRUCT *ads, const char *server ) { char *srv; - struct cldap_netlogon_reply cldap_reply; + struct nbt_cldap_netlogon_5 cldap_reply; if (!server || !*server) { return False; @@ -199,7 +199,7 @@ bool ads_try_connect(ADS_STRUCT *ads, const char *server ) /* Check the CLDAP reply flags */ - if ( !(cldap_reply.flags & ADS_LDAP) ) { + if ( !(cldap_reply.server_type & ADS_LDAP) ) { DEBUG(1,("ads_try_connect: %s's CLDAP reply says it is not an LDAP server!\n", srv)); SAFE_FREE( srv ); @@ -215,20 +215,20 @@ bool ads_try_connect(ADS_STRUCT *ads, const char *server ) SAFE_FREE(ads->config.client_site_name); SAFE_FREE(ads->server.workgroup); - ads->config.flags = cldap_reply.flags; - ads->config.ldap_server_name = SMB_STRDUP(cldap_reply.hostname); - strupper_m(cldap_reply.domain); - ads->config.realm = SMB_STRDUP(cldap_reply.domain); + ads->config.flags = cldap_reply.server_type; + ads->config.ldap_server_name = SMB_STRDUP(cldap_reply.pdc_dns_name); + ads->config.realm = SMB_STRDUP(cldap_reply.dns_domain); + strupper_m(ads->config.realm); ads->config.bind_path = ads_build_dn(ads->config.realm); - if (*cldap_reply.server_site_name) { + if (*cldap_reply.server_site) { ads->config.server_site_name = - SMB_STRDUP(cldap_reply.server_site_name); + SMB_STRDUP(cldap_reply.server_site); } - if (*cldap_reply.client_site_name) { + if (*cldap_reply.client_site) { ads->config.client_site_name = - SMB_STRDUP(cldap_reply.client_site_name); + SMB_STRDUP(cldap_reply.client_site); } - ads->server.workgroup = SMB_STRDUP(cldap_reply.netbios_domain); + ads->server.workgroup = SMB_STRDUP(cldap_reply.domain); ads->ldap.port = LDAP_PORT; if (!interpret_string_addr(&ads->ldap.ss, srv, 0)) { @@ -242,7 +242,7 @@ bool ads_try_connect(ADS_STRUCT *ads, const char *server ) SAFE_FREE(srv); /* Store our site name. */ - sitename_store( cldap_reply.domain, cldap_reply.client_site_name ); + sitename_store( cldap_reply.domain, cldap_reply.client_site); return True; } -- cgit From 1dd7ab38e7f7b5dae46cef4567957c71d6b5cc23 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 21 Apr 2008 19:47:13 +0200 Subject: cldap: add talloc context to ads_cldap_netlogon(). Guenther (This used to be commit 4cee7b1bd5cd97c414b73d6f39238958480cdcf3) --- source3/libads/cldap.c | 13 +++++++++---- source3/libads/ldap.c | 31 +++++++++++++++++++++---------- 2 files changed, 30 insertions(+), 14 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/cldap.c b/source3/libads/cldap.c index 6068ca4faf..be084c9df6 100644 --- a/source3/libads/cldap.c +++ b/source3/libads/cldap.c @@ -116,7 +116,9 @@ static void gotalarm_sig(void) /* receive a cldap netlogon reply */ -static int recv_cldap_netlogon(int sock, struct nbt_cldap_netlogon_5 *reply) +static int recv_cldap_netlogon(TALLOC_CTX *mem_ctx, + int sock, + struct nbt_cldap_netlogon_5 *reply) { int ret; ASN1_DATA data; @@ -182,7 +184,7 @@ static int recv_cldap_netlogon(int sock, struct nbt_cldap_netlogon_5 *reply) return -1; } - ndr_err = ndr_pull_union_blob_all(&os3, talloc_tos(), &p, 5, + ndr_err = ndr_pull_union_blob_all(&os3, mem_ctx, &p, 5, (ndr_pull_flags_fn_t)ndr_pull_nbt_cldap_netlogon); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return -1; @@ -208,7 +210,10 @@ static int recv_cldap_netlogon(int sock, struct nbt_cldap_netlogon_5 *reply) do a cldap netlogon query. Always 389/udp *******************************************************************/ -bool ads_cldap_netlogon(const char *server, const char *realm, struct nbt_cldap_netlogon_5 *reply) +bool ads_cldap_netlogon(TALLOC_CTX *mem_ctx, + const char *server, + const char *realm, + struct nbt_cldap_netlogon_5 *reply) { int sock; int ret; @@ -225,7 +230,7 @@ bool ads_cldap_netlogon(const char *server, const char *realm, struct nbt_cldap close(sock); return False; } - ret = recv_cldap_netlogon(sock, reply); + ret = recv_cldap_netlogon(mem_ctx, sock, reply); close(sock); if (ret == -1) { diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index b4a977056e..99df4ed8a3 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -177,6 +177,8 @@ bool ads_try_connect(ADS_STRUCT *ads, const char *server ) { char *srv; struct nbt_cldap_netlogon_5 cldap_reply; + TALLOC_CTX *mem_ctx = NULL; + bool ret = false; if (!server || !*server) { return False; @@ -185,16 +187,22 @@ bool ads_try_connect(ADS_STRUCT *ads, const char *server ) DEBUG(5,("ads_try_connect: sending CLDAP request to %s (realm: %s)\n", server, ads->server.realm)); + mem_ctx = talloc_init("ads_try_connect"); + if (!mem_ctx) { + DEBUG(0,("out of memory\n")); + return false; + } + /* this copes with inet_ntoa brokenness */ srv = SMB_STRDUP(server); ZERO_STRUCT( cldap_reply ); - if ( !ads_cldap_netlogon( srv, ads->server.realm, &cldap_reply ) ) { + if ( !ads_cldap_netlogon(mem_ctx, srv, ads->server.realm, &cldap_reply ) ) { DEBUG(3,("ads_try_connect: CLDAP request %s failed.\n", srv)); - SAFE_FREE( srv ); - return False; + ret = false; + goto out; } /* Check the CLDAP reply flags */ @@ -202,8 +210,8 @@ bool ads_try_connect(ADS_STRUCT *ads, const char *server ) if ( !(cldap_reply.server_type & ADS_LDAP) ) { DEBUG(1,("ads_try_connect: %s's CLDAP reply says it is not an LDAP server!\n", srv)); - SAFE_FREE( srv ); - return False; + ret = false; + goto out; } /* Fill in the ads->config values */ @@ -235,16 +243,19 @@ bool ads_try_connect(ADS_STRUCT *ads, const char *server ) DEBUG(1,("ads_try_connect: unable to convert %s " "to an address\n", srv)); - SAFE_FREE( srv ); - return False; + ret = false; + goto out; } - SAFE_FREE(srv); - /* Store our site name. */ sitename_store( cldap_reply.domain, cldap_reply.client_site); - return True; + ret = true; + out: + SAFE_FREE(srv); + TALLOC_FREE(mem_ctx); + + return ret; } /********************************************************************** -- cgit From bcbac69d1a38e128ffe8b763ac027d6eab33dcec Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 21 Apr 2008 19:59:27 +0200 Subject: cldap: avoid duplicate definitions so remove ads_cldap.h. Guenther (This used to be commit 538eefe22ad69540b9f73ffaa613d6be045de199) --- source3/libads/ldap.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 99df4ed8a3..b0f27b598b 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -151,14 +151,14 @@ bool ads_sitename_match(ADS_STRUCT *ads) bool ads_closest_dc(ADS_STRUCT *ads) { - if (ads->config.flags & ADS_CLOSEST) { - DEBUG(10,("ads_closest_dc: ADS_CLOSEST flag set\n")); + if (ads->config.flags & NBT_SERVER_CLOSEST) { + DEBUG(10,("ads_closest_dc: NBT_SERVER_CLOSEST flag set\n")); return True; } /* not sure if this can ever happen */ if (ads_sitename_match(ads)) { - DEBUG(10,("ads_closest_dc: ADS_CLOSEST flag not set but sites match\n")); + DEBUG(10,("ads_closest_dc: NBT_SERVER_CLOSEST flag not set but sites match\n")); return True; } @@ -207,7 +207,7 @@ bool ads_try_connect(ADS_STRUCT *ads, const char *server ) /* Check the CLDAP reply flags */ - if ( !(cldap_reply.server_type & ADS_LDAP) ) { + if ( !(cldap_reply.server_type & NBT_SERVER_LDAP) ) { DEBUG(1,("ads_try_connect: %s's CLDAP reply says it is not an LDAP server!\n", srv)); ret = false; -- cgit From 862d7e32b90f7020d46e025de918f6338f40441b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 21 Apr 2008 22:27:29 +0200 Subject: Move user/domain from rpc_pipe_client to cli_pipe_auth_data (This used to be commit 42de50d2cd43e760d776694f7b5f003ba51d7f84) --- source3/libads/ldap_printer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index 6682ec24d0..41f23b06a7 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -296,7 +296,8 @@ WERROR get_remote_printer_publishing_data(struct rpc_pipe_client *cli, result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS, - servername, cli->user_name, &pol); + servername, cli->auth->user_name, + &pol); if (!W_ERROR_IS_OK(result)) { DEBUG(3, ("Unable to open printer %s, error is %s.\n", printername, dos_errstr(result))); -- cgit From 778a5414b1148ea767020b5330b076fed666694f Mon Sep 17 00:00:00 2001 From: Steven Danneman Date: Fri, 25 Apr 2008 18:34:46 -0700 Subject: Fix bug 5419: memory leak in ads_do_search_all_args() when enumerating 1000s of entries The ads_do_search_all_args() function attempts to string together several LDAPMessage structures, returned across several paged ldap requests, into a single LDAPMessage structure. It does this by pulling entries off the second LDAPMessage structure and appending them to the first via the OpenLDAP specific ldap_add_result_entry() call. The problem with this approach is it skips non-entry messages such as the result, and controls. These messages are leaked. The short term solution as suggested by Volker is to replace the ads_*_entry() calls with ads_*_message() calls so we don't leak any messages. This fixes the leak but doesn't remove the dependence on the OpenLDAP specific implementation of ldap_add_result_entry(). (This used to be commit f1a5405409c396df394611e2a234522572d2860a) --- source3/libads/ldap.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index b0f27b598b..9321302151 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -870,8 +870,8 @@ static ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, /* this relies on the way that ldap_add_result_entry() works internally. I hope that this works on all ldap libs, but I have only tested with openldap */ - for (msg = ads_first_entry(ads, res2); msg; msg = next) { - next = ads_next_entry(ads, msg); + for (msg = ads_first_message(ads, res2); msg; msg = next) { + next = ads_next_message(ads, msg); ldap_add_result_entry((LDAPMessage **)res, msg); } /* note that we do not free res2, as the memory is now @@ -2090,6 +2090,28 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) return ldap_next_entry(ads->ldap.ld, res); } +/** + * pull the first message from a ADS result + * @param ads connection to ads server + * @param res Results of search + * @return first message from result + **/ + LDAPMessage *ads_first_message(ADS_STRUCT *ads, LDAPMessage *res) +{ + return ldap_first_message(ads->ldap.ld, res); +} + +/** + * pull the next message from a ADS result + * @param ads connection to ads server + * @param res Results of search + * @return next message from result + **/ + LDAPMessage *ads_next_message(ADS_STRUCT *ads, LDAPMessage *res) +{ + return ldap_next_message(ads->ldap.ld, res); +} + /** * pull a single string from a ADS result * @param ads connection to ads server -- cgit From 43c079ef26b6c5c1ee3c22c72d800d6131396993 Mon Sep 17 00:00:00 2001 From: "Gerald W. Carter" Date: Wed, 30 Apr 2008 09:57:15 -0500 Subject: BUG 5107: Fix handling of large DNS replies on AIX and Solaris. On AIX, Solaris, and possibly some older glibc systems (e.g. SLES8) truncated replies never give back a resp_len > buflen which ends up causing DNS resolve failures on large tcp DNS replies. Also add more debug lines about processing the DNS reply. (This used to be commit 5ed9b92097460cd8180db806a08213e97cfb8daa) --- source3/libads/dns.c | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/dns.c b/source3/libads/dns.c index 3239892814..fe0e6d3e86 100644 --- a/source3/libads/dns.c +++ b/source3/libads/dns.c @@ -203,8 +203,15 @@ static bool ads_dns_parse_rr_srv( TALLOC_CTX *ctx, uint8 *start, uint8 *end, DEBUG(1,("ads_dns_parse_rr_srv: Failed to uncompress name!\n")); return False; } + srv->hostname = talloc_strdup( ctx, dcname ); + DEBUG(10,("ads_dns_parse_rr_srv: Parsed %s [%u, %u, %u]\n", + srv->hostname, + srv->priority, + srv->weight, + srv->port)); + return True; } @@ -285,7 +292,7 @@ static NTSTATUS dns_send_req( TALLOC_CTX *ctx, const char *name, int q_type, uint8 **buf, int *resp_length ) { uint8 *buffer = NULL; - size_t buf_len; + size_t buf_len = 0; int resp_len = NS_PACKETSZ; static time_t last_dns_check = 0; static NTSTATUS last_dns_status = NT_STATUS_OK; @@ -346,7 +353,26 @@ static NTSTATUS dns_send_req( TALLOC_CTX *ctx, const char *name, int q_type, last_dns_check = time(NULL); return last_dns_status; } - } while ( buf_len < resp_len && resp_len < MAX_DNS_PACKET_SIZE ); + + /* On AIX, Solaris, and possibly some older glibc systems (e.g. SLES8) + truncated replies never give back a resp_len > buflen + which ends up causing DNS resolve failures on large tcp DNS replies */ + + if (buf_len == resp_len) { + if (resp_len == MAX_DNS_PACKET_SIZE) { + DEBUG(1,("dns_send_req: DNS reply too large when resolving %s\n", + name)); + TALLOC_FREE( buffer ); + last_dns_status = NT_STATUS_BUFFER_TOO_SMALL; + last_dns_check = time(NULL); + return last_dns_status; + } + + resp_len = MIN(resp_len*2, MAX_DNS_PACKET_SIZE); + } + + + } while ( buf_len < resp_len && resp_len <= MAX_DNS_PACKET_SIZE ); *buf = buffer; *resp_length = resp_len; @@ -429,7 +455,7 @@ static NTSTATUS ads_dns_lookup_srv( TALLOC_CTX *ctx, if (!ads_dns_parse_query(ctx, buffer, buffer+resp_len, &p, &q)) { DEBUG(1,("ads_dns_lookup_srv: " - "Failed to parse query record!\n")); + "Failed to parse query record [%d]!\n", rrnum)); return NT_STATUS_UNSUCCESSFUL; } } @@ -440,7 +466,7 @@ static NTSTATUS ads_dns_lookup_srv( TALLOC_CTX *ctx, if (!ads_dns_parse_rr_srv(ctx, buffer, buffer+resp_len, &p, &dcs[rrnum])) { DEBUG(1,("ads_dns_lookup_srv: " - "Failed to parse answer record!\n")); + "Failed to parse answer recordi [%d]!\n", rrnum)); return NT_STATUS_UNSUCCESSFUL; } } @@ -455,7 +481,7 @@ static NTSTATUS ads_dns_lookup_srv( TALLOC_CTX *ctx, if (!ads_dns_parse_rr( ctx, buffer, buffer+resp_len, &p, &rr)) { DEBUG(1,("ads_dns_lookup_srv: " - "Failed to parse authority record!\n")); + "Failed to parse authority record! [%d]\n", rrnum)); return NT_STATUS_UNSUCCESSFUL; } } @@ -469,7 +495,7 @@ static NTSTATUS ads_dns_lookup_srv( TALLOC_CTX *ctx, if (!ads_dns_parse_rr(ctx, buffer, buffer+resp_len, &p, &rr)) { DEBUG(1,("ads_dns_lookup_srv: Failed " - "to parse additional records section!\n")); + "to parse additional records section! [%d]\n", rrnum)); return NT_STATUS_UNSUCCESSFUL; } -- cgit From 1f6065765c148251488acd068fdea98717f7233f Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 5 May 2008 18:04:41 +0200 Subject: mailslot/cldap: use nt_version bits in queries. Guenther (This used to be commit b261f063125f8454d8f4e8f6b6f8aa5bc393ea34) --- source3/libads/cldap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/cldap.c b/source3/libads/cldap.c index be084c9df6..8b23ff9022 100644 --- a/source3/libads/cldap.c +++ b/source3/libads/cldap.c @@ -217,6 +217,7 @@ bool ads_cldap_netlogon(TALLOC_CTX *mem_ctx, { int sock; int ret; + uint32_t nt_version = NETLOGON_VERSION_5 | NETLOGON_VERSION_5EX; sock = open_udp_socket(server, LDAP_PORT ); if (sock == -1) { @@ -225,7 +226,7 @@ bool ads_cldap_netlogon(TALLOC_CTX *mem_ctx, return False; } - ret = send_cldap_netlogon(sock, realm, global_myname(), 6); + ret = send_cldap_netlogon(sock, realm, global_myname(), nt_version); if (ret != 0) { close(sock); return False; -- cgit From cdd9913c4a7d254ab3ef677737493f9f540272c7 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 7 May 2008 15:49:09 +0200 Subject: cldap: let ads_cldap_netlogon() return all possible cldap replies. Guenther (This used to be commit 6f9d5e1cc94bc90685b54c04622b8f3357bd2f69) --- source3/libads/cldap.c | 69 ++++++++++++++++++++++++++++++++++++++++---------- source3/libads/ldap.c | 2 +- 2 files changed, 56 insertions(+), 15 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/cldap.c b/source3/libads/cldap.c index 8b23ff9022..e4fa965a0f 100644 --- a/source3/libads/cldap.c +++ b/source3/libads/cldap.c @@ -3,6 +3,7 @@ net ads cldap functions Copyright (C) 2001 Andrew Tridgell (tridge@samba.org) Copyright (C) 2003 Jim McDonough (jmcd@us.ibm.com) + Copyright (C) 2008 Guenther Deschner (gd@samba.org) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -118,7 +119,8 @@ static void gotalarm_sig(void) */ static int recv_cldap_netlogon(TALLOC_CTX *mem_ctx, int sock, - struct nbt_cldap_netlogon_5 *reply) + uint32_t *nt_version, + union nbt_cldap_netlogon **reply) { int ret; ASN1_DATA data; @@ -129,8 +131,7 @@ static int recv_cldap_netlogon(TALLOC_CTX *mem_ctx, 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 p; - enum ndr_err_code ndr_err; + union nbt_cldap_netlogon *r = NULL; blob = data_blob(NULL, 8192); if (blob.data == NULL) { @@ -184,16 +185,23 @@ static int recv_cldap_netlogon(TALLOC_CTX *mem_ctx, return -1; } - ndr_err = ndr_pull_union_blob_all(&os3, mem_ctx, &p, 5, - (ndr_pull_flags_fn_t)ndr_pull_nbt_cldap_netlogon); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + 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; } - *reply = p.logon5; - - if (DEBUGLEVEL >= 10) { - NDR_PRINT_UNION_DEBUG(nbt_cldap_netlogon, 5, &p); + 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); @@ -203,6 +211,12 @@ static int recv_cldap_netlogon(TALLOC_CTX *mem_ctx, asn1_free(&data); + if (reply) { + *reply = r; + } else { + TALLOC_FREE(r); + } + return 0; } @@ -213,11 +227,11 @@ static int recv_cldap_netlogon(TALLOC_CTX *mem_ctx, bool ads_cldap_netlogon(TALLOC_CTX *mem_ctx, const char *server, const char *realm, - struct nbt_cldap_netlogon_5 *reply) + uint32_t *nt_version, + union nbt_cldap_netlogon **reply) { int sock; int ret; - uint32_t nt_version = NETLOGON_VERSION_5 | NETLOGON_VERSION_5EX; sock = open_udp_socket(server, LDAP_PORT ); if (sock == -1) { @@ -226,12 +240,12 @@ bool ads_cldap_netlogon(TALLOC_CTX *mem_ctx, return False; } - ret = send_cldap_netlogon(sock, realm, global_myname(), nt_version); + ret = send_cldap_netlogon(sock, realm, global_myname(), *nt_version); if (ret != 0) { close(sock); return False; } - ret = recv_cldap_netlogon(mem_ctx, sock, reply); + ret = recv_cldap_netlogon(mem_ctx, sock, nt_version, reply); close(sock); if (ret == -1) { @@ -240,3 +254,30 @@ bool ads_cldap_netlogon(TALLOC_CTX *mem_ctx, return True; } + +/******************************************************************* + do a cldap netlogon query. Always 389/udp +*******************************************************************/ + +bool ads_cldap_netlogon_5(TALLOC_CTX *mem_ctx, + const char *server, + const char *realm, + struct nbt_cldap_netlogon_5 *reply5) +{ + uint32_t nt_version = NETLOGON_VERSION_5 | NETLOGON_VERSION_5EX; + union nbt_cldap_netlogon *reply = NULL; + bool ret; + + ret = ads_cldap_netlogon(mem_ctx, server, realm, &nt_version, &reply); + if (!ret) { + return false; + } + + if (nt_version != (NETLOGON_VERSION_5 | NETLOGON_VERSION_5EX)) { + return false; + } + + *reply5 = reply->logon5; + + return true; +} diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 9321302151..24eb114f51 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -199,7 +199,7 @@ bool ads_try_connect(ADS_STRUCT *ads, const char *server ) ZERO_STRUCT( cldap_reply ); - if ( !ads_cldap_netlogon(mem_ctx, srv, ads->server.realm, &cldap_reply ) ) { + if ( !ads_cldap_netlogon_5(mem_ctx, srv, ads->server.realm, &cldap_reply ) ) { DEBUG(3,("ads_try_connect: CLDAP request %s failed.\n", srv)); ret = false; goto out; -- cgit From 4bd94c8338bef61477170bc41a8073739d55d812 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 7 May 2008 21:31:59 +0200 Subject: cldap: move out cldap object to fix the build. Guenther (This used to be commit 56be9c98d24e64bf855439df21766d30f448f407) --- source3/libads/cldap.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/cldap.c b/source3/libads/cldap.c index e4fa965a0f..3a5a8b0647 100644 --- a/source3/libads/cldap.c +++ b/source3/libads/cldap.c @@ -281,3 +281,87 @@ bool ads_cldap_netlogon_5(TALLOC_CTX *mem_ctx, return true; } + +/**************************************************************** +****************************************************************/ + +bool pull_mailslot_cldap_reply(TALLOC_CTX *mem_ctx, + const DATA_BLOB *blob, + union nbt_cldap_netlogon *r, + uint32_t *nt_version) +{ + enum ndr_err_code ndr_err; + uint32_t nt_version_query = ((*nt_version) & 0x000000ff); + uint16_t command = 0; + + ndr_err = ndr_pull_struct_blob(blob, mem_ctx, &command, + (ndr_pull_flags_fn_t)ndr_pull_uint16); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return false; + } + + switch (command) { + case 0x13: /* 19 */ + case 0x15: /* 21 */ + case 0x17: /* 23 */ + break; + default: + DEBUG(1,("got unexpected command: %d (0x%08x)\n", + command, command)); + return false; + } + + ndr_err = ndr_pull_union_blob_all(blob, mem_ctx, r, nt_version_query, + (ndr_pull_flags_fn_t)ndr_pull_nbt_cldap_netlogon); + if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + goto done; + } + + /* when the caller requested just those nt_version bits that the server + * was able to reply to, we are fine and all done. otherwise we need to + * assume downgraded replies which are painfully parsed here - gd */ + + if (nt_version_query & NETLOGON_VERSION_WITH_CLOSEST_SITE) { + nt_version_query &= ~NETLOGON_VERSION_WITH_CLOSEST_SITE; + } + ndr_err = ndr_pull_union_blob_all(blob, mem_ctx, r, nt_version_query, + (ndr_pull_flags_fn_t)ndr_pull_nbt_cldap_netlogon); + if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + goto done; + } + if (nt_version_query & NETLOGON_VERSION_5EX_WITH_IP) { + nt_version_query &= ~NETLOGON_VERSION_5EX_WITH_IP; + } + ndr_err = ndr_pull_union_blob_all(blob, mem_ctx, r, nt_version_query, + (ndr_pull_flags_fn_t)ndr_pull_nbt_cldap_netlogon); + if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + goto done; + } + if (nt_version_query & NETLOGON_VERSION_5EX) { + nt_version_query &= ~NETLOGON_VERSION_5EX; + } + ndr_err = ndr_pull_union_blob_all(blob, mem_ctx, r, nt_version_query, + (ndr_pull_flags_fn_t)ndr_pull_nbt_cldap_netlogon); + if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + goto done; + } + if (nt_version_query & NETLOGON_VERSION_5) { + nt_version_query &= ~NETLOGON_VERSION_5; + } + ndr_err = ndr_pull_union_blob_all(blob, mem_ctx, r, nt_version_query, + (ndr_pull_flags_fn_t)ndr_pull_nbt_cldap_netlogon); + if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + goto done; + } + + return false; + + done: + if (DEBUGLEVEL >= 10) { + NDR_PRINT_UNION_DEBUG(nbt_cldap_netlogon, nt_version_query, r); + } + + *nt_version = nt_version_query; + + return true; +} -- cgit From d59cf703ba5d6ac18e4399d12b043d5e68230403 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 9 May 2008 17:41:50 +0200 Subject: dsgetdcname: make use of nbt_cldap_netlogon_15. Guenther (This used to be commit 5b0eda98f3d127399770f7a037ad3277dbe23393) --- source3/libads/cldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/cldap.c b/source3/libads/cldap.c index 3a5a8b0647..efe13cc756 100644 --- a/source3/libads/cldap.c +++ b/source3/libads/cldap.c @@ -291,7 +291,7 @@ bool pull_mailslot_cldap_reply(TALLOC_CTX *mem_ctx, uint32_t *nt_version) { enum ndr_err_code ndr_err; - uint32_t nt_version_query = ((*nt_version) & 0x000000ff); + uint32_t nt_version_query = ((*nt_version) & 0x0000001f); uint16_t command = 0; ndr_err = ndr_pull_struct_blob(blob, mem_ctx, &command, -- cgit From 847d385f7bac1c02727d7655f4e277813d4fe42c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 14 May 2008 23:50:25 +0200 Subject: Fix Bug #5465 (joining with createcomputer=ou1/ou2/ou3). Guenther (This used to be commit f3251ba03a69c2fd0335861177159a32b2bc9477) --- source3/libads/ldap.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 24eb114f51..99fd645a3d 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -3595,18 +3595,18 @@ const char *ads_get_extended_right_name_by_guid(ADS_STRUCT *ads, ADS_STATUS ads_check_ou_dn(TALLOC_CTX *mem_ctx, ADS_STRUCT *ads, - const char *account_ou) + const char **account_ou) { struct ldb_dn *name_dn = NULL; const char *name = NULL; char *ou_string = NULL; - name_dn = ldb_dn_explode(mem_ctx, account_ou); + name_dn = ldb_dn_explode(mem_ctx, *account_ou); if (name_dn) { return ADS_SUCCESS; } - ou_string = ads_ou_string(ads, account_ou); + ou_string = ads_ou_string(ads, *account_ou); if (!ou_string) { return ADS_ERROR_LDAP(LDAP_INVALID_DN_SYNTAX); } @@ -3623,8 +3623,8 @@ ADS_STATUS ads_check_ou_dn(TALLOC_CTX *mem_ctx, return ADS_ERROR_LDAP(LDAP_INVALID_DN_SYNTAX); } - account_ou = talloc_strdup(mem_ctx, name); - if (!account_ou) { + *account_ou = talloc_strdup(mem_ctx, name); + if (!*account_ou) { return ADS_ERROR_LDAP(LDAP_NO_MEMORY); } -- cgit From eeb126a379d8d473e5e9a519b97bee543fb2b251 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 15 May 2008 16:38:32 +0200 Subject: libads/cldap: store client sitename also keyed by dns domain name. Guenther (This used to be commit 0388b2f0cc4d14b005c5b42f2c17ddcbc8bef12a) --- source3/libads/ldap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 99fd645a3d..063645febf 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -249,6 +249,7 @@ bool ads_try_connect(ADS_STRUCT *ads, const char *server ) /* Store our site name. */ sitename_store( cldap_reply.domain, cldap_reply.client_site); + sitename_store( cldap_reply.dns_domain, cldap_reply.client_site); ret = true; out: -- cgit From fc3e6851d3084717d0a1654f6b97f81aabe41e51 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 19 May 2008 02:48:09 +0200 Subject: Fix some comments to match get_kdc_ip_string()'s behaviour (This used to be commit 30956c784f58870ad552a3869d80f99872c31375) --- source3/libads/kerberos.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 66f203b12d..2adf6a4700 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -731,6 +731,9 @@ static char *print_kdc_line(char *mem_ctx, /************************************************************************ Create a string list of available kdc's, possibly searching by sitename. Does DNS queries. + + If "sitename" is given, the DC's in that site are listed first. + ************************************************************************/ static char *get_kdc_ip_string(char *mem_ctx, @@ -749,7 +752,10 @@ static char *get_kdc_ip_string(char *mem_ctx, return NULL; } - /* Get the KDC's only in this site. */ + /* + * First get the KDC's only in this site, the rest will be + * appended later + */ if (sitename) { -- cgit From fb37f156009611af0dd454a0fb0829a09cd638ac Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Tue, 29 Apr 2008 14:36:24 -0700 Subject: Cleanup size_t return values in callers of convert_string_allocate This patch is the second iteration of an inside-out conversion to cleanup functions in charcnv.c returning size_t == -1 to indicate failure. (This used to be commit 6b189dabc562d86dcaa685419d0cb6ea276f100d) --- source3/libads/ldap.c | 63 +++++++++++++++++++++++++++++-------------- source3/libads/ldap_printer.c | 19 +++++++++---- 2 files changed, 57 insertions(+), 25 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 063645febf..37c0c4d0ac 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -593,7 +593,8 @@ static char **ads_push_strvals(TALLOC_CTX *ctx, const char **in_vals) { char **values; int i; - + size_t size; + if (!in_vals) return NULL; for (i=0; in_vals[i]; i++) ; /* count values */ @@ -601,7 +602,7 @@ static char **ads_push_strvals(TALLOC_CTX *ctx, const char **in_vals) if (!values) return NULL; for (i=0; in_vals[i]; i++) { - if (push_utf8_talloc(ctx, &values[i], in_vals[i]) == (size_t) -1) { + if (!push_utf8_talloc(ctx, &values[i], in_vals[i], &size)) { TALLOC_FREE(values); return NULL; } @@ -616,6 +617,7 @@ static char **ads_pull_strvals(TALLOC_CTX *ctx, const char **in_vals) { char **values; int i; + size_t converted_size; if (!in_vals) return NULL; for (i=0; in_vals[i]; i++) @@ -624,7 +626,11 @@ static char **ads_pull_strvals(TALLOC_CTX *ctx, const char **in_vals) if (!values) return NULL; for (i=0; in_vals[i]; i++) { - pull_utf8_talloc(ctx, &values[i], in_vals[i]); + if (!pull_utf8_talloc(ctx, &values[i], in_vals[i], + &converted_size)) { + DEBUG(0,("ads_pull_strvals: pull_utf8_talloc failed: " + "%s", strerror(errno))); + } } return values; } @@ -652,6 +658,7 @@ static ADS_STATUS ads_do_paged_search_args(ADS_STRUCT *ads, { int rc, i, version; char *utf8_expr, *utf8_path, **search_attrs; + size_t converted_size; LDAPControl PagedResults, NoReferrals, ExternalCtrl, *controls[4], **rcontrols; BerElement *cookie_be = NULL; struct berval *cookie_bv= NULL; @@ -669,8 +676,9 @@ static ADS_STATUS ads_do_paged_search_args(ADS_STRUCT *ads, /* 0 means the conversion worked but the result was empty so we only fail if it's -1. In any case, it always at least nulls out the dest */ - if ((push_utf8_talloc(ctx, &utf8_expr, expr) == (size_t)-1) || - (push_utf8_talloc(ctx, &utf8_path, bind_path) == (size_t)-1)) { + if (!push_utf8_talloc(ctx, &utf8_expr, expr, &converted_size) || + !push_utf8_talloc(ctx, &utf8_path, bind_path, &converted_size)) + { rc = LDAP_NO_MEMORY; goto done; } @@ -967,6 +975,7 @@ ADS_STATUS ads_do_search_all_fn(ADS_STRUCT *ads, const char *bind_path, { int rc; char *utf8_expr, *utf8_path, **search_attrs = NULL; + size_t converted_size; TALLOC_CTX *ctx; *res = NULL; @@ -978,8 +987,9 @@ ADS_STATUS ads_do_search_all_fn(ADS_STRUCT *ads, const char *bind_path, /* 0 means the conversion worked but the result was empty so we only fail if it's negative. In any case, it always at least nulls out the dest */ - if ((push_utf8_talloc(ctx, &utf8_expr, expr) == (size_t)-1) || - (push_utf8_talloc(ctx, &utf8_path, bind_path) == (size_t)-1)) { + if (!push_utf8_talloc(ctx, &utf8_expr, expr, &converted_size) || + !push_utf8_talloc(ctx, &utf8_path, bind_path, &converted_size)) + { DEBUG(1,("ads_do_search: push_utf8_talloc() failed!")); rc = LDAP_NO_MEMORY; goto done; @@ -1077,6 +1087,7 @@ void ads_memfree(ADS_STRUCT *ads, void *mem) char *ads_get_dn(ADS_STRUCT *ads, LDAPMessage *msg) { char *utf8_dn, *unix_dn; + size_t converted_size; utf8_dn = ldap_get_dn(ads->ldap.ld, msg); @@ -1085,7 +1096,7 @@ void ads_memfree(ADS_STRUCT *ads, void *mem) return NULL; } - if (pull_utf8_allocate(&unix_dn, utf8_dn) == (size_t)-1) { + if (!pull_utf8_allocate(&unix_dn, utf8_dn, &converted_size)) { DEBUG(0,("ads_get_dn: string conversion failure utf8 [%s]\n", utf8_dn )); return NULL; @@ -1287,6 +1298,7 @@ ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, ADS_MODLIST mods) { int ret,i; char *utf8_dn = NULL; + size_t converted_size; /* this control is needed to modify that contains a currently non-existent attribute (but allowable for the object) to run @@ -1300,7 +1312,7 @@ ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, ADS_MODLIST mods) controls[0] = &PermitModify; controls[1] = NULL; - if (push_utf8_allocate(&utf8_dn, mod_dn) == -1) { + if (!push_utf8_allocate(&utf8_dn, mod_dn, &converted_size)) { return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); } @@ -1325,8 +1337,9 @@ ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ADS_MODLIST mods) { int ret, i; char *utf8_dn = NULL; + size_t converted_size; - if (push_utf8_allocate(&utf8_dn, new_dn) == -1) { + if (!push_utf8_allocate(&utf8_dn, new_dn, &converted_size)) { DEBUG(1, ("ads_gen_add: push_utf8_allocate failed!")); return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); } @@ -1351,7 +1364,8 @@ ADS_STATUS ads_del_dn(ADS_STRUCT *ads, char *del_dn) { int ret; char *utf8_dn = NULL; - if (push_utf8_allocate(&utf8_dn, del_dn) == -1) { + size_t converted_size; + if (!push_utf8_allocate(&utf8_dn, del_dn, &converted_size)) { DEBUG(1, ("ads_del_dn: push_utf8_allocate failed!")); return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); } @@ -2012,6 +2026,7 @@ static bool ads_dump_field(ADS_STRUCT *ads, char *field, void **values, void *da { LDAPMessage *msg; TALLOC_CTX *ctx; + size_t converted_size; if (!(ctx = talloc_init("ads_process_results"))) return; @@ -2031,7 +2046,14 @@ static bool ads_dump_field(ADS_STRUCT *ads, char *field, void **values, void *da char *field; bool string; - pull_utf8_talloc(ctx, &field, utf8_field); + if (!pull_utf8_talloc(ctx, &field, utf8_field, + &converted_size)) + { + DEBUG(0,("ads_process_results: " + "pull_utf8_talloc failed: %s", + strerror(errno))); + } + string = fn(ads, field, NULL, data_area); if (string) { @@ -2127,18 +2149,16 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) char **values; char *ret = NULL; char *ux_string; - size_t rc; + size_t converted_size; values = ldap_get_values(ads->ldap.ld, msg, field); if (!values) return NULL; - if (values[0]) { - rc = pull_utf8_talloc(mem_ctx, &ux_string, - values[0]); - if (rc != (size_t)-1) - ret = ux_string; - + if (values[0] && pull_utf8_talloc(mem_ctx, &ux_string, values[0], + &converted_size)) + { + ret = ux_string; } ldap_value_free(values); return ret; @@ -2159,6 +2179,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) char **values; char **ret = NULL; int i; + size_t converted_size; values = ldap_get_values(ads->ldap.ld, msg, field); if (!values) @@ -2173,7 +2194,9 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) } for (i=0;i<*num_values;i++) { - if (pull_utf8_talloc(mem_ctx, &ret[i], values[i]) == -1) { + if (!pull_utf8_talloc(mem_ctx, &ret[i], values[i], + &converted_size)) + { ldap_value_free(values); return NULL; } diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index 41f23b06a7..9935e2311a 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -103,17 +103,23 @@ static bool map_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods, const REGISTRY_VALUE *value) { char *str_value = NULL; + size_t converted_size; ADS_STATUS status; if (value->type != REG_SZ) - return False; + return false; if (value->size && *((smb_ucs2_t *) value->data_p)) { - pull_ucs2_talloc(ctx, &str_value, (const smb_ucs2_t *) value->data_p); + if (!pull_ucs2_talloc(ctx, &str_value, + (const smb_ucs2_t *) value->data_p, + &converted_size)) + { + return false; + } status = ads_mod_str(ctx, mods, value->valuename, str_value); return ADS_ERR_OK(status); } - return True; + return true; } @@ -163,6 +169,7 @@ static bool map_multi_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods, const REGISTRY_VALUE *value) { char **str_values = NULL; + size_t converted_size; smb_ucs2_t *cur_str = (smb_ucs2_t *) value->data_p; uint32 size = 0, num_vals = 0, i=0; ADS_STATUS status; @@ -185,9 +192,11 @@ static bool map_multi_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods, (num_vals + 1) * sizeof(char *)); cur_str = (smb_ucs2_t *) value->data_p; - for (i=0; i < num_vals; i++) + for (i=0; i < num_vals; i++) { cur_str += pull_ucs2_talloc(ctx, &str_values[i], - cur_str); + cur_str, &converted_size) ? + converted_size : (size_t)-1; + } status = ads_mod_strlist(ctx, mods, value->valuename, (const char **) str_values); -- cgit From d5d4a9511d763cc4a63d3020c5537e852da2ed4c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 27 May 2008 12:27:57 -0700 Subject: Memory leak fixes from Chere Zhou . Jeremy. (This used to be commit 201bcc8ed291b51be6f4508c6aa1cb17ce6dcbe3) --- source3/libads/kerberos.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 2adf6a4700..c4135f24a1 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -649,6 +649,10 @@ bool kerberos_secrets_store_salting_principal(const char *service, SAFE_FREE(princ_s); SAFE_FREE(unparsed_name); + if (princ) { + krb5_free_principal(context, princ); + } + if (context) { krb5_free_context(context); } -- cgit From ad00ecd3583af02dacdbb9d46881552b58467362 Mon Sep 17 00:00:00 2001 From: Marc VanHeyningen Date: Thu, 29 May 2008 10:00:46 -0700 Subject: Tiny memory leak (This used to be commit e7f76a0c65085dd1e7b50ea3537e11922e7d9ecd) --- source3/libads/util.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/util.c b/source3/libads/util.c index af96c3e10a..72f5dee80c 100644 --- a/source3/libads/util.c +++ b/source3/libads/util.c @@ -64,6 +64,8 @@ ADS_STATUS ads_guess_service_principal(ADS_STRUCT *ads, server_realm = SMB_STRDUP(ads->server.realm); if (!server || !server_realm) { + SAFE_FREE(server); + SAFE_FREE(server_realm); return ADS_ERROR(LDAP_NO_MEMORY); } -- cgit From d261e16cfd4afc19db0c26cfb2b6389c9c174310 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 5 Jun 2008 10:25:02 +0200 Subject: Fix a memleak in ads_find_dc() in case get_sorted_dc_list() fails This is really not a proper place to fix this, but as get_gc_list() and friends are about to be replaced anyway, just work around the broken existing API (This used to be commit df8d089bc63c2a52cbdf3504cded8df620a59902) --- source3/libads/ldap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 37c0c4d0ac..fc336d988b 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -319,6 +319,7 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads) status = get_sorted_dc_list(realm, sitename, &ip_list, &count, got_realm); if (!NT_STATUS_IS_OK(status)) { + SAFE_FREE(ip_list); /* fall back to netbios if we can */ if ( got_realm && !lp_disable_netbios() ) { got_realm = False; -- cgit From 21e759ef64ce75958c52c5c5215ee6f4d5151f25 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 5 Jun 2008 18:54:14 +0200 Subject: mailslot: always pull a command 25 type reply. Guenther (This used to be commit 1ce726b951621cb4b34069c31d1318fc04ad2389) --- source3/libads/cldap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libads') diff --git a/source3/libads/cldap.c b/source3/libads/cldap.c index efe13cc756..11565065af 100644 --- a/source3/libads/cldap.c +++ b/source3/libads/cldap.c @@ -304,6 +304,7 @@ bool pull_mailslot_cldap_reply(TALLOC_CTX *mem_ctx, case 0x13: /* 19 */ case 0x15: /* 21 */ case 0x17: /* 23 */ + case 0x19: /* 25 */ break; default: DEBUG(1,("got unexpected command: %d (0x%08x)\n", -- cgit From aaa2a4f447ea674080aad7bf00eabf9043ef9d4f Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 17 Jun 2008 12:20:54 +0200 Subject: Revert "Fix a memleak in ads_find_dc() in case get_sorted_dc_list() fails" This reverts commit df8d089bc63c2a52cbdf3504cded8df620a59902. (This used to be commit 342f8858200ed7c446516c270e1b4284d92010d8) --- source3/libads/ldap.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index fc336d988b..37c0c4d0ac 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -319,7 +319,6 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads) status = get_sorted_dc_list(realm, sitename, &ip_list, &count, got_realm); if (!NT_STATUS_IS_OK(status)) { - SAFE_FREE(ip_list); /* fall back to netbios if we can */ if ( got_realm && !lp_disable_netbios() ) { got_realm = False; -- cgit From 3688eeafa3679cec0d0b0954206d91d14f21a050 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 17 Jun 2008 16:17:03 +0200 Subject: libads: fix logic error in ads_get_kvno(). Guenther (This used to be commit 132b038581a1a91b4e70c7c44f97f52866609812) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 37c0c4d0ac..01c4b442c8 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1537,7 +1537,7 @@ uint32 ads_get_kvno(ADS_STRUCT *ads, const char *machine_name) } ret = ads_search(ads, &res, filter, attrs); SAFE_FREE(filter); - if (!ADS_ERR_OK(ret) && ads_count_replies(ads, res)) { + if (!ADS_ERR_OK(ret) || (ads_count_replies(ads, res) != 1)) { DEBUG(1,("ads_get_kvno: Computer Account For %s not found.\n", machine_name)); ads_msgfree(ads, res); return kvno; -- cgit From 0447e6a0a7f1b16f986f0fe5304cd65ee691277c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 17 Jun 2008 16:20:29 +0200 Subject: libads: add ads_get_machine_kvno() to make ads_get_kvno() a bit more generic. Guenther (This used to be commit cb7ace209c2051ae02647188715fa6ee324c2bf6) --- source3/libads/kerberos_keytab.c | 10 +++++----- source3/libads/ldap.c | 36 +++++++++++++++++++++++++++++------- 2 files changed, 34 insertions(+), 12 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c index d0161ada01..8e6983897f 100644 --- a/source3/libads/kerberos_keytab.c +++ b/source3/libads/kerberos_keytab.c @@ -312,9 +312,9 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc) } } - kvno = (krb5_kvno) ads_get_kvno(ads, global_myname()); + kvno = (krb5_kvno) ads_get_machine_kvno(ads, global_myname()); if (kvno == -1) { /* -1 indicates failure, everything else is OK */ - DEBUG(1,("ads_keytab_add_entry: ads_get_kvno failed to determine the system's kvno.\n")); + DEBUG(1,("ads_keytab_add_entry: ads_get_machine_kvno failed to determine the system's kvno.\n")); ret = -1; goto out; } @@ -380,7 +380,7 @@ int ads_keytab_flush(ADS_STRUCT *ads) goto out; } - kvno = (krb5_kvno) ads_get_kvno(ads, global_myname()); + kvno = (krb5_kvno) ads_get_machine_kvno(ads, global_myname()); if (kvno == -1) { /* -1 indicates a failure */ DEBUG(1,("ads_keytab_flush: Error determining the system's kvno.\n")); goto out; @@ -527,9 +527,9 @@ int ads_keytab_create_default(ADS_STRUCT *ads) /* Now loop through the keytab and update any other existing entries... */ - kvno = (krb5_kvno) ads_get_kvno(ads, machine_name); + kvno = (krb5_kvno) ads_get_machine_kvno(ads, machine_name); if (kvno == -1) { - DEBUG(1,("ads_keytab_create_default: ads_get_kvno failed to determine the system's kvno.\n")); + DEBUG(1,("ads_keytab_create_default: ads_get_machine_kvno failed to determine the system's kvno.\n")); return -1; } diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 01c4b442c8..7b9e51068b 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1516,13 +1516,13 @@ ADS_STATUS ads_add_strlist(TALLOC_CTX *ctx, ADS_MODLIST *mods, } /** - * Determines the computer account's current KVNO via an LDAP lookup + * Determines the an account's current KVNO via an LDAP lookup * @param ads An initialized ADS_STRUCT - * @param machine_name the NetBIOS name of the computer, which is used to identify the computer account. - * @return the kvno for the computer account, or -1 in case of a failure. + * @param account_name the NT samaccountname. + * @return the kvno for the account, or -1 in case of a failure. **/ -uint32 ads_get_kvno(ADS_STRUCT *ads, const char *machine_name) +uint32 ads_get_kvno(ADS_STRUCT *ads, const char *account_name) { LDAPMessage *res = NULL; uint32 kvno = (uint32)-1; /* -1 indicates a failure */ @@ -1531,14 +1531,14 @@ uint32 ads_get_kvno(ADS_STRUCT *ads, const char *machine_name) char *dn_string = NULL; ADS_STATUS ret = ADS_ERROR(LDAP_SUCCESS); - DEBUG(5,("ads_get_kvno: Searching for host %s\n", machine_name)); - if (asprintf(&filter, "(samAccountName=%s$)", machine_name) == -1) { + DEBUG(5,("ads_get_kvno: Searching for account %s\n", account_name)); + if (asprintf(&filter, "(samAccountName=%s)", account_name) == -1) { return kvno; } ret = ads_search(ads, &res, filter, attrs); SAFE_FREE(filter); if (!ADS_ERR_OK(ret) || (ads_count_replies(ads, res) != 1)) { - DEBUG(1,("ads_get_kvno: Computer Account For %s not found.\n", machine_name)); + DEBUG(1,("ads_get_kvno: Account for %s not found.\n", account_name)); ads_msgfree(ads, res); return kvno; } @@ -1573,6 +1573,28 @@ uint32 ads_get_kvno(ADS_STRUCT *ads, const char *machine_name) return kvno; } +/** + * Determines the computer account's current KVNO via an LDAP lookup + * @param ads An initialized ADS_STRUCT + * @param machine_name the NetBIOS name of the computer, which is used to identify the computer account. + * @return the kvno for the computer account, or -1 in case of a failure. + **/ + +uint32_t ads_get_machine_kvno(ADS_STRUCT *ads, const char *machine_name) +{ + char *computer_account = NULL; + uint32_t kvno = -1; + + if (asprintf(&computer_account, "%s$", machine_name) < 0) { + return kvno; + } + + kvno = ads_get_kvno(ads, computer_account); + free(computer_account); + + return kvno; +} + /** * This clears out all registered spn's for a given hostname * @param ads An initilaized ADS_STRUCT -- cgit From 0ac8c5d49a8b0d5535eebf80871003f6c19af5eb Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 18 Jun 2008 12:45:57 +0200 Subject: kerberos: make smb_krb5_kt_add_entry public, allow to pass keys without salting them. Guenther (This used to be commit 7c4da23be1105dc224033b21eb486e7fcdc7d9c5) --- source3/libads/kerberos_keytab.c | 16 ++++++++++------ source3/libads/kerberos_verify.c | 2 +- 2 files changed, 11 insertions(+), 7 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c index 8e6983897f..c8ffd734fc 100644 --- a/source3/libads/kerberos_keytab.c +++ b/source3/libads/kerberos_keytab.c @@ -32,9 +32,13 @@ /********************************************************************** **********************************************************************/ -static int smb_krb5_kt_add_entry( krb5_context context, krb5_keytab keytab, - krb5_kvno kvno, const char *princ_s, - krb5_enctype *enctypes, krb5_data password ) +int smb_krb5_kt_add_entry(krb5_context context, + krb5_keytab keytab, + krb5_kvno kvno, + const char *princ_s, + krb5_enctype *enctypes, + krb5_data password, + bool no_salt) { krb5_error_code ret = 0; krb5_kt_cursor cursor; @@ -166,7 +170,7 @@ static int smb_krb5_kt_add_entry( krb5_context context, krb5_keytab keytab, #ifdef HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK /* Heimdal */ keyp = &kt_entry.keyblock; #endif - if (create_kerberos_key_from_string(context, princ, &password, keyp, enctypes[i])) { + if (create_kerberos_key_from_string(context, princ, &password, keyp, enctypes[i], no_salt)) { continue; } @@ -321,7 +325,7 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc) /* add the fqdn principal to the keytab */ - ret = smb_krb5_kt_add_entry( context, keytab, kvno, princ_s, enctypes, password ); + ret = smb_krb5_kt_add_entry( context, keytab, kvno, princ_s, enctypes, password, false ); if ( ret ) { DEBUG(1,("ads_keytab_add_entry: Failed to add entry to keytab file\n")); goto out; @@ -330,7 +334,7 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc) /* add the short principal name if we have one */ if ( short_princ_s ) { - ret = smb_krb5_kt_add_entry( context, keytab, kvno, short_princ_s, enctypes, password ); + ret = smb_krb5_kt_add_entry( context, keytab, kvno, short_princ_s, enctypes, password, false ); if ( ret ) { DEBUG(1,("ads_keytab_add_entry: Failed to add short entry to keytab file\n")); goto out; diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index a4d7a8e680..c667181642 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -259,7 +259,7 @@ static krb5_error_code ads_secrets_verify_ticket(krb5_context context, goto out; } - if (create_kerberos_key_from_string(context, host_princ, &password, key, enctypes[i])) { + if (create_kerberos_key_from_string(context, host_princ, &password, key, enctypes[i], false)) { SAFE_FREE(key); continue; } -- cgit From 6b4b76c40e965c7544097aa652eb6455af2ae8c1 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 24 Jun 2008 12:11:06 +0200 Subject: libads: add ADS_AUTH_USER_CREDS to avoid magic overwriting of usernames. Guenther (This used to be commit b5aaf5aa0f280f69e05b613271c96473a79b812e) --- source3/libads/kerberos.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index c4135f24a1..31e5af4224 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -323,6 +323,11 @@ int ads_kinit_password(ADS_STRUCT *ads) const char *account_name; fstring acct_name; + if (ads->auth.flags & ADS_AUTH_USER_CREDS) { + account_name = ads->auth.user_name; + goto got_accountname; + } + if ( IS_DC ) { /* this will end up getting a ticket for DOMAIN@RUSTED.REA.LM */ account_name = lp_workgroup(); @@ -338,6 +343,7 @@ int ads_kinit_password(ADS_STRUCT *ads) account_name = ads->auth.user_name; } + got_accountname: if (asprintf(&s, "%s@%s", account_name, ads->auth.realm) == -1) { return KRB5_CC_NOMEM; } -- cgit From 7b1f015675b99c3ee8620bd0113b817a910a0727 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 24 Jun 2008 13:02:03 +0200 Subject: libads: add ads_connect_user_creds() that won't overwrite given user creds. Guenther (This used to be commit 026018c9f1ed0680b3ca5b26dd6b8dc466e27e0d) --- source3/libads/ldap.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 7b9e51068b..7c64082ab4 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -526,6 +526,18 @@ got_connection: return status; } +/** + * Connect to the LDAP server using given credentials + * @param ads Pointer to an existing ADS_STRUCT + * @return status of connection + **/ +ADS_STATUS ads_connect_user_creds(ADS_STRUCT *ads) +{ + ads->auth.flags |= ADS_AUTH_USER_CREDS; + + return ads_connect(ads); +} + /** * Disconnect the LDAP server * @param ads Pointer to an existing ADS_STRUCT -- cgit From 9ff1ffcbee46257c3b2b13b84c2a539322493190 Mon Sep 17 00:00:00 2001 From: "Gerald W. Carter" Date: Fri, 27 Jun 2008 10:22:39 -0400 Subject: libads: Add API call to connect to a global catalog server. Extends ads_connect() to a new call ads_connect_gc() which connects on port 3268 rather than port 389. Also makes ads_try_connect() static and only used internally to ldap.c (This used to be commit f4c37dbe2c986fb7bfe510cdff3b4a9fbc06d079) --- source3/libads/ldap.c | 145 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 140 insertions(+), 5 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 7c64082ab4..b59dab1f13 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -173,7 +173,7 @@ bool ads_closest_dc(ADS_STRUCT *ads) try a connection to a given ldap server, returning True and setting the servers IP in the ads struct if successful */ -bool ads_try_connect(ADS_STRUCT *ads, const char *server ) +static bool ads_try_connect(ADS_STRUCT *ads, const char *server, bool gc) { char *srv; struct nbt_cldap_netlogon_5 cldap_reply; @@ -238,7 +238,7 @@ bool ads_try_connect(ADS_STRUCT *ads, const char *server ) } ads->server.workgroup = SMB_STRDUP(cldap_reply.domain); - ads->ldap.port = LDAP_PORT; + ads->ldap.port = gc ? LDAP_GC_PORT : LDAP_PORT; if (!interpret_string_addr(&ads->ldap.ss, srv, 0)) { DEBUG(1,("ads_try_connect: unable to convert %s " "to an address\n", @@ -358,7 +358,7 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads) } } - if ( ads_try_connect(ads, server) ) { + if ( ads_try_connect(ads, server, false) ) { SAFE_FREE(ip_list); SAFE_FREE(sitename); return NT_STATUS_OK; @@ -385,6 +385,141 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads) return NT_STATUS_NO_LOGON_SERVERS; } +/********************************************************************* + *********************************************************************/ + +static NTSTATUS ads_lookup_site(void) +{ + ADS_STRUCT *ads = NULL; + ADS_STATUS ads_status; + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + struct nbt_cldap_netlogon_5 cldap_reply; + + ZERO_STRUCT(cldap_reply); + + ads = ads_init(lp_realm(), NULL, NULL); + if (!ads) { + return NT_STATUS_NO_MEMORY; + } + + /* The NO_BIND here will find a DC and set the client site + but not establish the TCP connection */ + + ads->auth.flags = ADS_AUTH_NO_BIND; + ads_status = ads_connect(ads); + if (!ADS_ERR_OK(ads_status)) { + DEBUG(4, ("ads_lookup_site: ads_connect to our realm failed! (%s)\n", + ads_errstr(ads_status))); + } + nt_status = ads_ntstatus(ads_status); + + if (ads) { + ads_destroy(&ads); + } + + return nt_status; +} + +/********************************************************************* + *********************************************************************/ + +static const char* host_dns_domain(const char *fqdn) +{ + const char *p = fqdn; + + /* go to next char following '.' */ + + if ((p = strchr_m(fqdn, '.')) != NULL) { + p++; + } + + return p; +} + + +/** + * Connect to the Global Catalog server + * @param ads Pointer to an existing ADS_STRUCT + * @return status of connection + * + * Simple wrapper around ads_connect() that fills in the + * GC ldap server information + **/ + +ADS_STATUS ads_connect_gc(ADS_STRUCT *ads) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct dns_rr_srv *gcs_list; + int num_gcs; + char *realm = ads->server.realm; + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + ADS_STATUS ads_status = ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL); + int i; + bool done = false; + char *sitename = NULL; + + if (!realm) + realm = lp_realm(); + + if ((sitename = sitename_fetch(realm)) == NULL) { + ads_lookup_site(); + sitename = sitename_fetch(realm); + } + + do { + /* We try once with a sitename and once without + (unless we don't have a sitename and then we're + done */ + + if (sitename == NULL) + done = true; + + nt_status = ads_dns_query_gcs(frame, realm, sitename, + &gcs_list, &num_gcs); + + SAFE_FREE(sitename); + + if (!NT_STATUS_IS_OK(nt_status)) { + ads_status = ADS_ERROR_NT(nt_status); + goto done; + } + + /* Loop until we get a successful connection or have gone + through them all. When connecting a GC server, make sure that + the realm is the server's DNS name and not the forest root */ + + for (i=0; iserver.gc = true; + ads->server.ldap_server = SMB_STRDUP(gcs_list[i].hostname); + ads->server.realm = SMB_STRDUP(host_dns_domain(ads->server.ldap_server)); + ads_status = ads_connect(ads); + if (ADS_ERR_OK(ads_status)) { + /* Reset the bind_dn to "". A Global Catalog server + may host multiple domain trees in a forest. + Windows 2003 GC server will accept "" as the search + path to imply search all domain trees in the forest */ + + SAFE_FREE(ads->config.bind_path); + ads->config.bind_path = SMB_STRDUP(""); + + + goto done; + } + SAFE_FREE(ads->server.ldap_server); + SAFE_FREE(ads->server.realm); + } + + TALLOC_FREE(gcs_list); + num_gcs = 0; + } while (!done); + +done: + SAFE_FREE(sitename); + talloc_destroy(frame); + + return ads_status; +} + /** * Connect to the LDAP server @@ -412,7 +547,7 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) } if (ads->server.ldap_server && - ads_try_connect(ads, ads->server.ldap_server)) { + ads_try_connect(ads, ads->server.ldap_server, ads->server.gc)) { goto got_connection; } @@ -472,7 +607,7 @@ got_connection: /* Otherwise setup the TCP LDAP session */ ads->ldap.ld = ldap_open_with_timeout(ads->config.ldap_server_name, - LDAP_PORT, lp_ldap_timeout()); + ads->ldap.port, lp_ldap_timeout()); if (ads->ldap.ld == NULL) { status = ADS_ERROR(LDAP_OPERATIONS_ERROR); goto out; -- cgit From 893e3522fc9a9cb1ef677ce1232525f51a8cc95e Mon Sep 17 00:00:00 2001 From: "Gerald W. Carter" Date: Sat, 28 Jun 2008 09:35:07 -0400 Subject: Return NULL in sitename_fetch() if gencache_init() fails. Not false (This used to be commit 8704c2ab37479236788c0a99465d73643d3d555a) --- source3/libads/dns.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/dns.c b/source3/libads/dns.c index fe0e6d3e86..3a9e849668 100644 --- a/source3/libads/dns.c +++ b/source3/libads/dns.c @@ -796,7 +796,7 @@ char *sitename_fetch(const char *realm) char *key; if (!gencache_init()) { - return False; + return NULL; } if (!realm || (strlen(realm) == 0)) { -- cgit From 52635c6f58edaa0e948851fd3f06b95d05ab10a4 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 30 Jun 2008 10:29:15 +0200 Subject: kerberos: rename smb_krb5_kt_add_entry to smb_krb5_kt_add_entry_ext. Guenther (This used to be commit 48600a0019d70d22574cf08e8fe19d44cc332a0f) --- source3/libads/kerberos_keytab.c | 64 ++++++++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 25 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c index c8ffd734fc..04804fc27c 100644 --- a/source3/libads/kerberos_keytab.c +++ b/source3/libads/kerberos_keytab.c @@ -32,13 +32,13 @@ /********************************************************************** **********************************************************************/ -int smb_krb5_kt_add_entry(krb5_context context, - krb5_keytab keytab, - krb5_kvno kvno, - const char *princ_s, - krb5_enctype *enctypes, - krb5_data password, - bool no_salt) +int smb_krb5_kt_add_entry_ext(krb5_context context, + krb5_keytab keytab, + krb5_kvno kvno, + const char *princ_s, + krb5_enctype *enctypes, + krb5_data password, + bool no_salt) { krb5_error_code ret = 0; krb5_kt_cursor cursor; @@ -52,20 +52,20 @@ int smb_krb5_kt_add_entry(krb5_context context, ret = smb_krb5_parse_name(context, princ_s, &princ); if (ret) { - DEBUG(1,("smb_krb5_kt_add_entry: smb_krb5_parse_name(%s) failed (%s)\n", princ_s, error_message(ret))); + DEBUG(1,("smb_krb5_kt_add_entry_ext: smb_krb5_parse_name(%s) failed (%s)\n", princ_s, error_message(ret))); goto out; } /* Seek and delete old keytab entries */ ret = krb5_kt_start_seq_get(context, keytab, &cursor); if (ret != KRB5_KT_END && ret != ENOENT ) { - DEBUG(3,("smb_krb5_kt_add_entry: Will try to delete old keytab entries\n")); + DEBUG(3,("smb_krb5_kt_add_entry_ext: Will try to delete old keytab entries\n")); while(!krb5_kt_next_entry(context, keytab, &kt_entry, &cursor)) { bool compare_name_ok = False; ret = smb_krb5_unparse_name(context, kt_entry.principal, &ktprinc); if (ret) { - DEBUG(1,("smb_krb5_kt_add_entry: smb_krb5_unparse_name failed (%s)\n", + DEBUG(1,("smb_krb5_kt_add_entry_ext: smb_krb5_unparse_name failed (%s)\n", error_message(ret))); goto out; } @@ -86,7 +86,7 @@ int smb_krb5_kt_add_entry(krb5_context context, #endif if (!compare_name_ok) { - DEBUG(10,("smb_krb5_kt_add_entry: ignoring keytab entry principal %s, kvno = %d\n", + DEBUG(10,("smb_krb5_kt_add_entry_ext: ignoring keytab entry principal %s, kvno = %d\n", ktprinc, kt_entry.vno)); } @@ -94,39 +94,38 @@ int smb_krb5_kt_add_entry(krb5_context context, if (compare_name_ok) { if (kt_entry.vno == kvno - 1) { - DEBUG(5,("smb_krb5_kt_add_entry: Saving previous (kvno %d) entry for principal: %s.\n", + DEBUG(5,("smb_krb5_kt_add_entry_ext: Saving previous (kvno %d) entry for principal: %s.\n", kvno - 1, princ_s)); } else { - - DEBUG(5,("smb_krb5_kt_add_entry: Found old entry for principal: %s (kvno %d) - trying to remove it.\n", + DEBUG(5,("smb_krb5_kt_add_entry_ext: Found old entry for principal: %s (kvno %d) - trying to remove it.\n", princ_s, kt_entry.vno)); ret = krb5_kt_end_seq_get(context, keytab, &cursor); ZERO_STRUCT(cursor); if (ret) { - DEBUG(1,("smb_krb5_kt_add_entry: krb5_kt_end_seq_get() failed (%s)\n", + DEBUG(1,("smb_krb5_kt_add_entry_ext: krb5_kt_end_seq_get() failed (%s)\n", error_message(ret))); goto out; } ret = krb5_kt_remove_entry(context, keytab, &kt_entry); if (ret) { - DEBUG(1,("smb_krb5_kt_add_entry: krb5_kt_remove_entry failed (%s)\n", + DEBUG(1,("smb_krb5_kt_add_entry_ext: krb5_kt_remove_entry failed (%s)\n", error_message(ret))); goto out; } - DEBUG(5,("smb_krb5_kt_add_entry: removed old entry for principal: %s (kvno %d).\n", + DEBUG(5,("smb_krb5_kt_add_entry_ext: removed old entry for principal: %s (kvno %d).\n", princ_s, kt_entry.vno)); ret = krb5_kt_start_seq_get(context, keytab, &cursor); if (ret) { - DEBUG(1,("smb_krb5_kt_add_entry: krb5_kt_start_seq failed (%s)\n", + DEBUG(1,("smb_krb5_kt_add_entry_ext: krb5_kt_start_seq failed (%s)\n", error_message(ret))); goto out; } ret = smb_krb5_kt_free_entry(context, &kt_entry); ZERO_STRUCT(kt_entry); if (ret) { - DEBUG(1,("smb_krb5_kt_add_entry: krb5_kt_remove_entry failed (%s)\n", + DEBUG(1,("smb_krb5_kt_add_entry_ext: krb5_kt_remove_entry failed (%s)\n", error_message(ret))); goto out; } @@ -138,7 +137,7 @@ int smb_krb5_kt_add_entry(krb5_context context, ret = smb_krb5_kt_free_entry(context, &kt_entry); ZERO_STRUCT(kt_entry); if (ret) { - DEBUG(1,("smb_krb5_kt_add_entry: smb_krb5_kt_free_entry failed (%s)\n", error_message(ret))); + DEBUG(1,("smb_krb5_kt_add_entry_ext: smb_krb5_kt_free_entry failed (%s)\n", error_message(ret))); goto out; } } @@ -146,7 +145,7 @@ int smb_krb5_kt_add_entry(krb5_context context, ret = krb5_kt_end_seq_get(context, keytab, &cursor); ZERO_STRUCT(cursor); if (ret) { - DEBUG(1,("smb_krb5_kt_add_entry: krb5_kt_end_seq_get failed (%s)\n",error_message(ret))); + DEBUG(1,("smb_krb5_kt_add_entry_ext: krb5_kt_end_seq_get failed (%s)\n",error_message(ret))); goto out; } } @@ -177,13 +176,13 @@ int smb_krb5_kt_add_entry(krb5_context context, kt_entry.principal = princ; kt_entry.vno = kvno; - DEBUG(3,("smb_krb5_kt_add_entry: adding keytab entry for (%s) with encryption type (%d) and version (%d)\n", + DEBUG(3,("smb_krb5_kt_add_entry_ext: adding keytab entry for (%s) with encryption type (%d) and version (%d)\n", princ_s, enctypes[i], kt_entry.vno)); ret = krb5_kt_add_entry(context, keytab, &kt_entry); krb5_free_keyblock_contents(context, keyp); ZERO_STRUCT(kt_entry); if (ret) { - DEBUG(1,("smb_krb5_kt_add_entry: adding entry to keytab failed (%s)\n", error_message(ret))); + DEBUG(1,("smb_krb5_kt_add_entry_ext: adding entry to keytab failed (%s)\n", error_message(ret))); goto out; } } @@ -212,6 +211,21 @@ out: return (int)ret; } +int smb_krb5_kt_add_entry(krb5_context context, + krb5_keytab keytab, + krb5_kvno kvno, + const char *princ_s, + krb5_enctype *enctypes, + krb5_data password) +{ + return smb_krb5_kt_add_entry_ext(context, + keytab, + kvno, + princ_s, + enctypes, + password, + false); +} /********************************************************************** Adds a single service principal, i.e. 'host' to the system keytab @@ -325,7 +339,7 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc) /* add the fqdn principal to the keytab */ - ret = smb_krb5_kt_add_entry( context, keytab, kvno, princ_s, enctypes, password, false ); + ret = smb_krb5_kt_add_entry( context, keytab, kvno, princ_s, enctypes, password ); if ( ret ) { DEBUG(1,("ads_keytab_add_entry: Failed to add entry to keytab file\n")); goto out; @@ -334,7 +348,7 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc) /* add the short principal name if we have one */ if ( short_princ_s ) { - ret = smb_krb5_kt_add_entry( context, keytab, kvno, short_princ_s, enctypes, password, false ); + ret = smb_krb5_kt_add_entry( context, keytab, kvno, short_princ_s, enctypes, password ); if ( ret ) { DEBUG(1,("ads_keytab_add_entry: Failed to add short entry to keytab file\n")); goto out; -- cgit From 16e44ee1126a5126346689785d240ac37a32fad7 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 30 Jun 2008 10:32:15 +0200 Subject: kerberos: allow to keep entries with old kvno's while creating keytab. Guenther (This used to be commit 6194244bd9fcc1fb736f3d91433f107270cac1c9) --- source3/libads/kerberos_keytab.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c index 04804fc27c..b905cb4a0f 100644 --- a/source3/libads/kerberos_keytab.c +++ b/source3/libads/kerberos_keytab.c @@ -38,7 +38,8 @@ int smb_krb5_kt_add_entry_ext(krb5_context context, const char *princ_s, krb5_enctype *enctypes, krb5_data password, - bool no_salt) + bool no_salt, + bool keep_old_entries) { krb5_error_code ret = 0; krb5_kt_cursor cursor; @@ -96,7 +97,7 @@ int smb_krb5_kt_add_entry_ext(krb5_context context, if (kt_entry.vno == kvno - 1) { DEBUG(5,("smb_krb5_kt_add_entry_ext: Saving previous (kvno %d) entry for principal: %s.\n", kvno - 1, princ_s)); - } else { + } else if (!keep_old_entries) { DEBUG(5,("smb_krb5_kt_add_entry_ext: Found old entry for principal: %s (kvno %d) - trying to remove it.\n", princ_s, kt_entry.vno)); ret = krb5_kt_end_seq_get(context, keytab, &cursor); @@ -224,6 +225,7 @@ int smb_krb5_kt_add_entry(krb5_context context, princ_s, enctypes, password, + false, false); } -- cgit From 962beb287239b525ed4828ae13b85de31448d256 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 3 Jul 2008 15:15:57 +0200 Subject: Pass NULL to gencache_get when we are not interested in the timeout value (This used to be commit 16062dfc3dcc8f1ca0024a3ae21effb889c7ffc0) --- source3/libads/dns.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/dns.c b/source3/libads/dns.c index 3a9e849668..a8825d32e6 100644 --- a/source3/libads/dns.c +++ b/source3/libads/dns.c @@ -790,7 +790,6 @@ bool sitename_store(const char *realm, const char *sitename) char *sitename_fetch(const char *realm) { char *sitename = NULL; - time_t timeout; bool ret = False; const char *query_realm; char *key; @@ -807,7 +806,7 @@ char *sitename_fetch(const char *realm) key = sitename_key(query_realm); - ret = gencache_get( key, &sitename, &timeout ); + ret = gencache_get( key, &sitename, NULL ); SAFE_FREE(key); if ( !ret ) { DEBUG(5,("sitename_fetch: No stored sitename for %s\n", -- cgit From d3def9a18cc701573530154ed420278f007f06a3 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 11 Jul 2008 17:44:25 +0200 Subject: Revert "Pass NULL to gencache_get when we are not interested in the timeout value" This reverts commit 16062dfc3dcc8f1ca0024a3ae21effb889c7ffc0. (This used to be commit 114ca8577568cdb5a81d8734f1d1d096f1b36c36) --- source3/libads/dns.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/dns.c b/source3/libads/dns.c index a8825d32e6..3a9e849668 100644 --- a/source3/libads/dns.c +++ b/source3/libads/dns.c @@ -790,6 +790,7 @@ bool sitename_store(const char *realm, const char *sitename) char *sitename_fetch(const char *realm) { char *sitename = NULL; + time_t timeout; bool ret = False; const char *query_realm; char *key; @@ -806,7 +807,7 @@ char *sitename_fetch(const char *realm) key = sitename_key(query_realm); - ret = gencache_get( key, &sitename, NULL ); + ret = gencache_get( key, &sitename, &timeout ); SAFE_FREE(key); if ( !ret ) { DEBUG(5,("sitename_fetch: No stored sitename for %s\n", -- cgit From c11fb13864a9cec6c5a798031339c53c513a071f Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 18 Jul 2008 16:41:34 +0200 Subject: kerberos: make smb_krb5_kt_add_entry() static. Guenther (This used to be commit 04b1847f87d166819dfe0f8c27c8cd9fc062544f) --- source3/libads/kerberos_keytab.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c index b905cb4a0f..87b85550c5 100644 --- a/source3/libads/kerberos_keytab.c +++ b/source3/libads/kerberos_keytab.c @@ -212,12 +212,12 @@ out: return (int)ret; } -int smb_krb5_kt_add_entry(krb5_context context, - krb5_keytab keytab, - krb5_kvno kvno, - const char *princ_s, - krb5_enctype *enctypes, - krb5_data password) +static int smb_krb5_kt_add_entry(krb5_context context, + krb5_keytab keytab, + krb5_kvno kvno, + const char *princ_s, + krb5_enctype *enctypes, + krb5_data password) { return smb_krb5_kt_add_entry_ext(context, keytab, -- cgit From d701d23b604dd21288e894b7d286de206eca2857 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 30 Jul 2008 16:06:30 -0700 Subject: Fix uninitialized variables. Jeremy. (This used to be commit 1db7e00a5400863fd5dbb81c1a4c6ea6092d0495) --- source3/libads/kerberos_keytab.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c index 87b85550c5..77a50e4221 100644 --- a/source3/libads/kerberos_keytab.c +++ b/source3/libads/kerberos_keytab.c @@ -276,6 +276,7 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc) ret = -1; goto out; } + ZERO_STRUCT(password); password.data = password_s; password.length = strlen(password_s); -- cgit From 825f06c3f98cc5393761612903297d7a61b70b3b Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 20 Aug 2008 21:17:35 +0200 Subject: libads: remove unused vars. Guenther (This used to be commit ea9fc3bea31b11e715d9524defc18b75e5943842) --- source3/libads/ldap.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index b59dab1f13..eb45e3a0dd 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -393,9 +393,6 @@ static NTSTATUS ads_lookup_site(void) ADS_STRUCT *ads = NULL; ADS_STATUS ads_status; NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - struct nbt_cldap_netlogon_5 cldap_reply; - - ZERO_STRUCT(cldap_reply); ads = ads_init(lp_realm(), NULL, NULL); if (!ads) { -- cgit From bff20e14c38d7139033127182b76aa24e471b581 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 22 Aug 2008 14:58:01 +0200 Subject: kerberos: use KRB5_KT_KEY macro where appropriate. Guenther (This used to be commit a042dffd7121bda3dbc9509f69fcfae06ed4cc22) --- source3/libads/kerberos_keytab.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c index 77a50e4221..883f582445 100644 --- a/source3/libads/kerberos_keytab.c +++ b/source3/libads/kerberos_keytab.c @@ -161,15 +161,8 @@ int smb_krb5_kt_add_entry_ext(krb5_context context, for (i = 0; enctypes[i]; i++) { krb5_keyblock *keyp; -#if !defined(HAVE_KRB5_KEYTAB_ENTRY_KEY) && !defined(HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK) -#error krb5_keytab_entry has no key or keyblock member -#endif -#ifdef HAVE_KRB5_KEYTAB_ENTRY_KEY /* MIT */ - keyp = &kt_entry.key; -#endif -#ifdef HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK /* Heimdal */ - keyp = &kt_entry.keyblock; -#endif + keyp = KRB5_KT_KEY(&kt_entry); + if (create_kerberos_key_from_string(context, princ, &password, keyp, enctypes[i], no_salt)) { continue; } -- cgit From 862ff66da912e840860452ef0846793961f3bb82 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 4 Sep 2008 15:11:22 +0200 Subject: kerberos: fix indent of enc type lines in generated krb5.conf files. Guenther (This used to be commit 18a26f08b6fab4119a1421a7ca59c32dde8bb8cb) --- source3/libads/kerberos.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 31e5af4224..501ef010fd 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -893,9 +893,9 @@ bool create_local_private_krb5_conf_for_domain(const char *realm, file_contents = talloc_asprintf(fname, "[libdefaults]\n\tdefault_realm = %s\n" - "default_tgs_enctypes = RC4-HMAC DES-CBC-CRC DES-CBC-MD5\n" - "default_tkt_enctypes = RC4-HMAC DES-CBC-CRC DES-CBC-MD5\n" - "preferred_enctypes = RC4-HMAC DES-CBC-CRC DES-CBC-MD5\n\n" + "\tdefault_tgs_enctypes = RC4-HMAC DES-CBC-CRC DES-CBC-MD5\n" + "\tdefault_tkt_enctypes = RC4-HMAC DES-CBC-CRC DES-CBC-MD5\n" + "\tpreferred_enctypes = RC4-HMAC DES-CBC-CRC DES-CBC-MD5\n\n" "[realms]\n\t%s = {\n" "\t%s\t}\n", realm_upper, realm_upper, kdc_ip_string); -- cgit