+#define LDAP_AUTH_OTHERKIND 0x86L
+#define LDAP_AUTH_NEGOTIATE (LDAP_AUTH_OTHERKIND | 0x0400)
/*--
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
#define NEED_SOCKETS
+#ifndef _WIN32
+#include "port-sockets.h"
+#endif
#include <krb5.h>
+#ifdef HAVE_KRB4
#include <krb.h>
+#endif
#include <ldap.h>
#ifdef _WIN32
#include <wshelper.h>
-#include "k5-int.h"
-#include "adm_err.h"
#include "krb5_err.h"
#else
#include <sys/socket.h>
#endif
#ifdef _WIN32
+extern krb5_error_code decode_krb5_error
+ (const krb5_data *output, krb5_error **rep);
#define sleep(Seconds) Sleep(Seconds * 1000)
#define gethostbyname(Server) rgethostbyname(Server)
#endif
int get_krb5_error(krb5_error_code rc, char *in, char *out);
int ad_connect(LDAP **ldap_handle, char *ldap_domain, char *dn_path,
char *Win2kPassword, char *Win2kUser, char *default_server,
- int connect_to_kdc);
+ int connect_to_kdc, char **ServerList);
int ad_kdc_connect(char *connectedServer);
int ad_server_connect(char *connectedServer, char *domain);
void ad_kdc_disconnect();
long myrandom();
void generate_password(char *password);
+
+#ifdef WIN32
krb5_error_code encode_krb5_setpw
PROTOTYPE((const krb5_setpw *rep, krb5_data ** code));
+#endif
krb5_error_code make_setpw_req(krb5_context context, krb5_auth_context auth_context,
krb5_data *ap_req, krb5_principal targprinc,
krb5_data clearresult;
krb5_error *krberror;
krb5_replay_data replay;
- krb5_keyblock *tmp;
krb5_ap_rep_enc_part *ap_rep_enc;
if (packet->length < 4)
/* verify length */
plen = (*ptr++ & 0xff);
plen = (plen<<8) | (*ptr++ & 0xff);
- if (plen != packet->length)
+ if (plen != (int)packet->length)
return(KRB5KRB_AP_ERR_MODIFIED);
vno = (*ptr++ & 0xff);
vno = (vno<<8) | (*ptr++ & 0xff);
/* XXX there's no api to do this right. The problem is that
if there's a remote subkey, it will be used. This is
not what the spec requires */
- tmp = auth_context->remote_subkey;
- auth_context->remote_subkey = NULL;
ret = krb5_rd_priv(context, auth_context, &cipherresult, &clearresult,
&replay);
- auth_context->remote_subkey = tmp;
if (ret)
return(ret);
}
{
if ((cc = sendto(kdc_socket, chpw_snd.data, chpw_snd.length, 0,
NULL,
- 0)) != chpw_snd.length)
+ 0)) != (int)chpw_snd.length)
{
code = KDC_SEND_ERROR;
sleep(1);
int ad_connect(LDAP **ldap_handle, char *ldap_domain, char *dn_path,
char *Win2kPassword, char *Win2kUser, char *default_server,
- int connect_to_kdc)
+ int connect_to_kdc, char **ServerList)
{
int i;
- int j;
+ int k;
+ int Count;
char *server_name[MAX_SERVER_NAMES];
- char server_array[MAX_SERVER_NAMES][256];
static char temp[128];
ULONG version = LDAP_VERSION3;
ULONG rc;
- int Max_wait_time = 500;
+ int Max_wait_time = 1000;
int Max_size_limit = LDAP_NO_LIMIT;
- if (ldap_domain == NULL)
- ldap_domain = "win.mit.edu";
+ if (strlen(ldap_domain) == 0)
+ return(1);
+
convert_domain_to_dn(ldap_domain, dn_path);
if (strlen(dn_path) == 0)
- return(1);
+ return(1);
+
+ Count = 0;
+ while (ServerList[Count] != NULL)
+ ++Count;
+
+ if ((Count == 0) && (connect_to_kdc))
+ return(1);
memset(server_name, 0, sizeof(server_name[0]) * MAX_SERVER_NAMES);
- memset(server_array, 0, sizeof(server_array[0]) * MAX_SERVER_NAMES);
- if (strlen(default_server) == 0)
+ if (locate_ldap_server(ldap_domain, server_name) == -1)
+ return(1);
+
+ for (i = 0; i < MAX_SERVER_NAMES; i++)
{
- if (locate_ldap_server(ldap_domain, server_name) == -1)
- return(2);
- j = 0;
- for (i = 0; i < MAX_SERVER_NAMES; i++)
+ if (server_name[i] != NULL)
{
- if (server_name[i] != NULL)
+ if (Count >= MAX_SERVER_NAMES)
{
- strcpy(server_array[i], server_name[i]);
free(server_name[i]);
- j++;
+ server_name[i] = NULL;
+ continue;
+ }
+ for (k = 0; k < (int)strlen(server_name[i]); k++)
+ server_name[i][k] = toupper(server_name[i][k]);
+ for (k = 0; k < Count; k++)
+ {
+ if (!strcasecmp(server_name[i], ServerList[k]))
+ {
+ free(server_name[i]);
+ server_name[i] = NULL;
+ break;
+ }
+ }
+ if (k == Count)
+ {
+ ServerList[Count] = calloc(1, 256);
+ strcpy(ServerList[Count], server_name[i]);
+ ServerList[Count] = (char *)strdup((char *)server_name[i]);
+ ++Count;
+ free(server_name[i]);
}
}
- if (j == 0)
- return(2);
- qsort((void *)server_array, (size_t)j, sizeof(server_array[0]), compare_elements);
}
- else
- strcpy(server_array[0], default_server);
-
- for (i = 0; i < MAX_SERVER_NAMES; i++)
+
+ for (i = 0; i < Count; i++)
{
- if (strlen(server_array[i]) != 0)
+ if (ServerList[i] == NULL)
+ continue;
+
+ if (((*ldap_handle) = ldap_open(ServerList[i], LDAP_PORT)) != NULL)
{
- if (((*ldap_handle) = ldap_open(server_array[i], LDAP_PORT)) != NULL)
+ rc = ldap_set_option((*ldap_handle), LDAP_OPT_PROTOCOL_VERSION, &version);
+ rc = ldap_set_option((*ldap_handle), LDAP_OPT_TIMELIMIT,
+ (void *)&Max_wait_time);
+ rc = ldap_set_option((*ldap_handle), LDAP_OPT_SIZELIMIT,
+ (void *)&Max_size_limit);
+ rc = ldap_set_option((*ldap_handle), LDAP_OPT_REFERRALS, LDAP_OPT_OFF);
+ rc = ldap_adgssapi_bind((*ldap_handle), dn_path, 0);
+ if (rc == LDAP_SUCCESS)
{
- rc = ldap_set_option((*ldap_handle), LDAP_OPT_PROTOCOL_VERSION, &version);
- rc = ldap_set_option((*ldap_handle), LDAP_OPT_TIMELIMIT,
- (void *)&Max_wait_time);
- rc = ldap_set_option((*ldap_handle), LDAP_OPT_SIZELIMIT,
- (void *)&Max_size_limit);
- rc = ldap_set_option((*ldap_handle), LDAP_OPT_REFERRALS, LDAP_OPT_OFF);
- rc = ldap_adgssapi_bind((*ldap_handle), dn_path, GSSSASL_PRIVACY_PROTECTION);
- if (rc == LDAP_SUCCESS)
+ if (connect_to_kdc)
{
- if (connect_to_kdc)
+ if (!ad_server_connect(ServerList[i], ldap_domain))
{
- if (!ad_server_connect(server_array[i], ldap_domain))
- {
- ldap_unbind_s((*ldap_handle));
- continue;
- }
+ ldap_unbind_s((*ldap_handle));
+ (*ldap_handle) = NULL;
+ continue;
}
- if (strlen(default_server) == 0)
- strcpy(default_server, server_array[i]);
- strcpy(connected_server, server_array[i]);
- break;
}
+ if (strlen(default_server) == 0)
+ strcpy(default_server, ServerList[i]);
+ strcpy(connected_server, ServerList[i]);
+ break;
+ }
+ else
+ {
+ (*ldap_handle) = NULL;
}
}
}
- if (i >= MAX_SERVER_NAMES)
- return(3);
+ if ((*ldap_handle) == NULL)
+ return(1);
return(0);
}
return(-1);
return(rc);
}
-