#include <sys/types.h>
#ifndef _WIN32
#include <sys/uio.h>
+#include <sys/socket.h>
#include <netinet/in.h>
#endif
+#include <arpa/nameser.h>
+#include <resolv.h>
+#include <lber.h>
#include <krb5.h>
#include "ldap-int.h"
#include "gssldap-int.h"
typedef gss_uint32 OM_uint32;
#endif
+char ldap_domain_name[128];
+
+#ifndef T_SRV
+#define T_SRV 33
+#endif
+#define LDAP_SERVICE "_ldap"
+#define TCP_PROTOCOL "_tcp"
+
+int locate_ldap_server(char *domain, char **server_name);
int ldap_delete_tickets(LDAP *ld, char *service_name);
-static int negotiate_security_options(gssldap_client_state_t state, int layer);
+static int negotiate_security_options(gssldap_client_state_t state,
+ int layer);
int ldap_reset_principal(LDAP *ld, char *service_name, gss_name_t target_name);
-unsigned long gsssasl_pack_security_token(OM_uint32 *min_stat,
- gss_ctx_id_t context,
- gsssasl_security_negotiation_t inmask,
- size_t masklength,
- gss_buffer_t wrapped_tok);
+unsigned long gsssasl_pack_security_token(OM_uint32 *min_stat, gss_ctx_id_t context,
+ gsssasl_security_negotiation_t inmask,
+ size_t masklength, gss_buffer_t wrapped_tok);
+
int gsssasl_unpack_security_token(OM_uint32 *min_stat, gss_ctx_id_t context,
- gss_buffer_t wrapped_tok,
- gsssasl_security_negotiation_t *outmask,
- size_t *masklength);
+ gss_buffer_t wrapped_tok,
+ gsssasl_security_negotiation_t *outmask,
+ size_t *masklength);
#ifdef GSSSASL_DEBUG
static int debug_ = 1;
#define TRACE(x)
#define LDAP_PERROR(ld, x)
#define LOG_STATUS(msg, min, maj)
-#endif /* GSSSASL_DEBUG */
+#endif /* GSSSASL_DEBUG */
#ifdef HACK_SERVICE_NAME
char *__service = NULL;
static int security_layer = 0;
static int security_token_size = 0;
+LDAP_CALLBACK int LDAP_C ldap_gssapi_read(LBER_SOCKET sock, void *data,
+ int len)
+{
+ OM_uint32 maj_stat;
+ OM_uint32 min_stat;
+ OM_uint32 rc;
+ OM_uint32 pdulen;
+ gss_buffer_desc recv_tok;
+ gss_buffer_desc wrapped_tok;
+
+ if (security_layer &
+ (GSSSASL_INTEGRITY_PROTECTION | GSSSASL_PRIVACY_PROTECTION))
+ {
+ if (recv(sock, (char *)&pdulen, sizeof(pdulen), 0) != sizeof(pdulen))
+ return (0);
+ wrapped_tok.length = ntohl(pdulen);
+#ifdef GSSSASL_DEBUG
+ if (debug_)
+ {
+ fprintf(stderr, "Reading data of %d octets\n",
+ wrapped_tok.length);
+ }
+#endif /* GSSSASL_DEBUG */
+ if ((int)wrapped_tok.length > security_token_size)
+ return (0);
+ wrapped_tok.value = malloc(wrapped_tok.length);
+ if (wrapped_tok.value == NULL)
+ return (0);
+ if (recv(sock, wrapped_tok.value, wrapped_tok.length, 0)
+ != (int)wrapped_tok.length)
+ {
+ gss_release_buffer(&rc, &wrapped_tok);
+ return (0);
+ }
+ maj_stat = gss_unwrap(&min_stat,
+ security_context,
+ &wrapped_tok,
+ &recv_tok,
+ &rc,
+ (gss_qop_t *) NULL);
+ if (maj_stat != GSS_S_COMPLETE)
+ {
+ gss_release_buffer(&rc, &wrapped_tok);
+ return maj_stat;
+ }
+#ifdef GSSSASL_DEBUG
+ if (debug_)
+ {
+ fprintf(stderr, "Got %d bytes of %s data\n",
+ recv_tok.length, rc ? "private" : "signed");
+ }
+#endif /* GSSSASL_DEBUG */
+ if ((int)recv_tok.length > len)
+ {
+ gss_release_buffer(&rc, &recv_tok);
+ gss_release_buffer(&rc, &wrapped_tok);
+ return GSS_S_FAILURE;
+ }
+ memcpy(data, recv_tok.value, recv_tok.length);
+ pdulen = recv_tok.length;
+ gss_release_buffer(&rc, &recv_tok);
+ gss_release_buffer(&rc, &wrapped_tok);
+
+ return pdulen;
+ }
+ else
+ return read(sock, data, len);
+}
+
+LDAP_CALLBACK int LDAP_C ldap_gssapi_write(LBER_SOCKET sock, const void *data,
+ int len)
+{
+ OM_uint32 maj_stat;
+ OM_uint32 min_stat;
+ OM_uint32 pdulen;
+ OM_uint32 rc;
+ gss_buffer_desc send_tok;
+ gss_buffer_desc wrapped_tok;
+ unsigned char *ptr;
+
+ if (security_layer &
+ (GSSSASL_INTEGRITY_PROTECTION | GSSSASL_PRIVACY_PROTECTION))
+ {
+ send_tok.length = len;
+ send_tok.value = (void *) data;
+#ifdef GSSSASL_DEBUG
+ if (debug_)
+ {
+ fprintf(stderr, "Sending %d bytes of data\n",
+ len);
+ }
+#endif /* GSSSASL_DEBUG */
+ maj_stat = gss_wrap(&min_stat,
+ security_context,
+ (security_layer & GSSSASL_PRIVACY_PROTECTION) ? 1 : 0,
+ GSS_C_QOP_DEFAULT,
+ &send_tok,
+ &rc,
+ &wrapped_tok);
+ if (maj_stat != GSS_S_COMPLETE)
+ return maj_stat;
+#ifdef GSSSASL_DEBUG
+ if (debug_)
+ {
+ fprintf(stderr, "Sent %d bytes of %s data\n",
+ wrapped_tok.length, rc ? "private" : "signed");
+ }
+#endif /* GSSSASL_DEBUG */
+ pdulen = htonl(wrapped_tok.length);
+ ptr = calloc(1, sizeof(pdulen) + wrapped_tok.length);
+ memcpy(ptr, &pdulen, sizeof(pdulen));
+ memcpy(&ptr[sizeof(pdulen)], wrapped_tok.value, wrapped_tok.length);
+ rc = send(sock, ptr, sizeof(pdulen) + wrapped_tok.length, 0);
+ free(ptr);
+ if (rc == (wrapped_tok.length + sizeof(pdulen)))
+ rc = len;
+ gss_release_buffer(&maj_stat, &wrapped_tok);
+ return rc;
+ }
+ else
+ return send(sock, data, len, 0);
+}
+
#ifdef GSSSASL_DEBUG
/*
* Dump the token to stderr
{
int i;
unsigned char *p = tok->value;
-
+
for (i = 0; i < (int)tok->length; i++, p++)
{
fprintf(stderr, "%02x ", *p);
if ((i % 16) == 15)
- fprintf(stderr, "\n");
+ {
+ fprintf(stderr, "\n");
+ }
}
fprintf(stderr, "\n");
fflush(stderr);
msg_ctx = 0;
while (1)
{
- maj_stat = gss_display_status(&min_stat, res, type, GSS_C_NULL_OID,
- &msg_ctx, &msg);
+ maj_stat = gss_display_status(&min_stat,
+ res,
+ type,
+ GSS_C_NULL_OID,
+ &msg_ctx,
+ &msg);
if (debug_)
- fprintf(stderr, "ldap_adgssapi_bind: %s: %s\n", (char *) msg.value,
- reason);
+ {
+ fprintf(stderr, "ldap_adgssapi_bind: %s: %s\n",
+ (char *) msg.value,
+ reason);
+ }
(void) gss_release_buffer(&min_stat, &msg);
if (!msg_ctx)
- break;
+ break;
}
return;
}
/*
* Cover function to handle a GSS-API error
*/
-static void log_status(const char *reason, OM_uint32 maj_stat,
- OM_uint32 min_stat)
+static void log_status(const char *reason, OM_uint32 maj_stat,
+ OM_uint32 min_stat)
{
log_status_impl(reason, maj_stat, GSS_C_GSS_CODE);
log_status_impl(reason, min_stat, GSS_C_MECH_CODE);
return;
}
-#endif /* GSSSASL_DEBUG */
+#endif /* GSSSASL_DEBUG */
/*
* Send a GSS-API token as part of a SASL BindRequest
cred.bv_val = send_tok->value;
cred.bv_len = send_tok->length;
- if (ldap_sasl_bind(state->ld, state->binddn, GSSAPI_SASL_NAME, &cred,
- NULL, NULL, &state->msgid) != LDAP_SUCCESS)
- {
+ if (ldap_sasl_bind(state->ld,
+ state->binddn,
+ GSSAPI_SASL_NAME,
+ &cred,
+ NULL,
+ NULL,
+ &state->msgid) != LDAP_SUCCESS)
+ {
LDAP_PERROR(state->ld, "send_token");
TRACE("<== send_token");
return -1;
TRACE("==> parse_bind_result");
- if (ldap_result(state->ld, state->msgid, LDAP_MSG_ALL, NULL, &res) <= 0)
+ if (ldap_result(state->ld,
+ state->msgid,
+ LDAP_MSG_ALL,
+ NULL,
+ &res) <= 0)
{
LDAP_PERROR(state->ld, "ldap_result");
TRACE("<== parse_bind_result");
return -1;
}
- for (msg = ldap_first_message(state->ld, res); msg != NULL;
- msg = ldap_next_message(state->ld, msg))
+ for (msg = ldap_first_message(state->ld, res);
+ msg != NULL;
+ msg = ldap_next_message(state->ld, msg))
{
if (ldap_msgtype(msg) == LDAP_RES_BIND)
- {
- ldap_parse_result(state->ld, msg, &rc, NULL, NULL, NULL, NULL, 0);
- break;
- }
- }
+ {
+ ldap_parse_result(state->ld, msg, &rc, NULL, NULL, NULL, NULL, 0);
+ break;
+ }
+ }
ldap_msgfree(res);
state->msgid = -1;
-
+
TRACE("<== parse_bind_result");
-
+
if (rc == LDAP_SUCCESS)
- return 0;
-
+ {
+ return 0;
+ }
state->rc = rc;
return -1;
}
recv_tok->value = NULL;
recv_tok->length = 0;
- for (msg = ldap_first_message(state->ld, res); msg != NULL;
- msg = ldap_next_message(state->ld, msg))
+ for (msg = ldap_first_message(state->ld, res);
+ msg != NULL;
+ msg = ldap_next_message(state->ld, msg))
{
- if (ldap_msgtype(msg) == LDAP_RES_BIND && servercred == NULL)
- {
- rc = ldap_parse_sasl_bind_result(state->ld, msg, &servercred, 0);
- if (rc == LDAP_SUCCESS && servercred != NULL)
- {
- recv_tok->value = malloc(servercred->bv_len);
- if (recv_tok->value != NULL)
- {
- memcpy(recv_tok->value, servercred->bv_val,
- servercred->bv_len);
- recv_tok->length = servercred->bv_len;
- }
- break;
- }
- else
- {
- state->rc = rc;
- }
- }
- }
+ if (ldap_msgtype(msg) == LDAP_RES_BIND && servercred == NULL)
+ {
+ rc = ldap_parse_sasl_bind_result(state->ld,
+ msg,
+ &servercred,
+ 0);
+ if (rc == LDAP_SUCCESS && servercred != NULL)
+ {
+ recv_tok->value = malloc(servercred->bv_len);
+ if (recv_tok->value != NULL)
+ {
+ memcpy(recv_tok->value, servercred->bv_val, servercred->bv_len);
+ recv_tok->length = servercred->bv_len;
+ }
+ break;
+ }
+ else
+ {
+ state->rc = rc;
+ }
+ }
+ }
ldap_msgfree(res);
state->msgid = -1;
TRACE("<== recv_token");
if (servercred != NULL)
{
- nslberi_free(servercred);
+ nslberi_free(servercred);
TRACE("<== recv_token");
return 0;
- }
+ }
if (state->rc == LDAP_SUCCESS)
- state->rc = LDAP_OPERATIONS_ERROR;
+ {
+ state->rc = LDAP_OPERATIONS_ERROR;
+ }
else
- LDAP_PERROR(state->ld, "recv_token");
-
+ {
+ LDAP_PERROR(state->ld, "recv_token");
+ }
+
TRACE("<== recv_token");
return -1;
}
* to GSS_Init_sec_context, repeating the actions in this paragraph.
*/
static int client_establish_context(LDAP *ld, gssldap_client_state_t state,
- char *service_name)
+ char *service_name)
{
gss_buffer_desc send_tok;
gss_buffer_desc recv_tok;
gss_buffer_desc *token_ptr;
- gss_name_t target_name;
- OM_uint32 maj_stat;
- OM_uint32 min_stat;
- gss_OID oid = GSS_C_NULL_OID;
- OM_uint32 ret_flags;
+ gss_name_t target_name;
+ OM_uint32 maj_stat;
+ OM_uint32 min_stat;
+ gss_OID oid = GSS_C_NULL_OID;
+ OM_uint32 ret_flags;
TRACE("==> client_establish_context");
send_tok.value = service_name;
send_tok.length = strlen(send_tok.value) + 1;
- maj_stat = gss_import_name(&min_stat, &send_tok,
- (gss_OID) gss_nt_service_name, &target_name);
+ maj_stat = gss_import_name(&min_stat,
+ &send_tok,
+ (gss_OID) gss_nt_service_name,
+ &target_name);
if (ldap_reset_principal(ld, service_name, target_name))
{
TRACE("<== client_establish_context");
token_ptr = GSS_C_NO_BUFFER;
state->context = GSS_C_NO_CONTEXT;
-
+
do
{
- maj_stat = gss_init_sec_context(&min_stat, GSS_C_NO_CREDENTIAL,
- &state->context, target_name, oid,
- GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG,
- 0, NULL, token_ptr, NULL, &send_tok,
- &ret_flags, NULL);
+ maj_stat = gss_init_sec_context(&min_stat,
+ GSS_C_NO_CREDENTIAL,
+ &state->context,
+ target_name,
+ oid,
+ GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG,
+ 0,
+ NULL,
+ token_ptr,
+ NULL,
+ &send_tok,
+ &ret_flags,
+ NULL);
if (token_ptr != GSS_C_NO_BUFFER)
- (void) gss_release_buffer(&min_stat, &recv_tok);
+ (void) gss_release_buffer(&min_stat, &recv_tok);
if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTINUE_NEEDED)
- {
- LOG_STATUS("initializing context", maj_stat, min_stat);
- (void) gss_release_name(&min_stat, &target_name);
- TRACE("<== client_establish_context");
- return -1;
- }
+ {
+ LOG_STATUS("initializing context", maj_stat, min_stat);
+ (void) gss_release_name(&min_stat, &target_name);
+ TRACE("<== client_establish_context");
+ return -1;
+ }
#ifdef GSSSASL_DEBUG
if (debug_)
- {
- fprintf(stderr, "Sending init_sec_context token (size=%d)...\n",
- send_tok.length);
- fflush(stderr);
- print_token(&send_tok);
- }
+ {
+ fprintf(stderr, "Sending init_sec_context token (size=%d)...\n",
+ send_tok.length);
+ fflush(stderr);
+ print_token(&send_tok);
+ }
#endif
if (send_token(state, &send_tok) < 0)
- {
- TRACE("Send_token failed");
- (void) gss_release_buffer(&min_stat, &send_tok);
- (void) gss_release_name(&min_stat, &target_name);
- TRACE("<== client_establish_context");
- return -1;
- }
+ {
+ TRACE("Send_token failed");
+ (void) gss_release_buffer(&min_stat, &send_tok);
+ (void) gss_release_name(&min_stat, &target_name);
+ TRACE("<== client_establish_context");
+ return -1;
+ }
(void) gss_release_buffer(&min_stat, &send_tok);
if (maj_stat == GSS_S_CONTINUE_NEEDED)
- {
- TRACE("continue needed...");
- if (recv_token(state, &recv_tok) < 0)
- {
- TRACE("recv_token failed");
- (void) gss_release_name(&min_stat, &target_name);
- TRACE("<== client_establish_context");
- return -1;
- }
+ {
+ TRACE("continue needed...");
+ if (recv_token(state, &recv_tok) < 0)
+ {
+ TRACE("recv_token failed");
+ (void) gss_release_name(&min_stat, &target_name);
+ TRACE("<== client_establish_context");
+ return -1;
+ }
#ifdef GSSSASL_DEBUG
- if (debug_)
- {
- fprintf(stderr, "Received token (size=%d)...\n",
- recv_tok.length);
- fflush(stderr);
- print_token(&recv_tok);
- }
+ if (debug_)
+ {
+ fprintf(stderr, "Received token (size=%d)...\n",
+ recv_tok.length);
+ fflush(stderr);
+ print_token(&recv_tok);
+ }
#endif
- token_ptr = &recv_tok;
- }
+ token_ptr = &recv_tok;
+ }
} while (maj_stat == GSS_S_CONTINUE_NEEDED);
(void) gss_release_name(&min_stat, &target_name);
-
+
TRACE("<== client_establish_context");
return 0;
}
* generated output_message. The client can then consider the server
* authenticated.
*/
-static int negotiate_security_options(gssldap_client_state_t state, int layer)
+static int negotiate_security_options(gssldap_client_state_t state,
+ int layer)
{
- OM_uint32 maj_stat;
- OM_uint32 min_stat;
+ OM_uint32 maj_stat;
+ OM_uint32 min_stat;
gss_buffer_desc recv_tok;
gss_buffer_desc send_tok;
- OM_uint32 rc;
- size_t mask_length;
- gsssasl_security_negotiation_t send_mask;
- gsssasl_security_negotiation_t recv_mask;
-
+ OM_uint32 rc;
+ size_t mask_length;
+ gsssasl_security_negotiation_t send_mask;
+ gsssasl_security_negotiation_t recv_mask;
+
TRACE("==> negotiate_security_options");
-
+
memset(&send_tok, '\0', sizeof(send_tok));
memset(&recv_tok, '\0', sizeof(recv_tok));
if ((rc = recv_token(state, &recv_tok)) < 0)
}
#ifdef GSSSASL_DEBUG
if (debug_)
- {
- fprintf(stderr, "Received token (size=%d)...\n",
- recv_tok.length);
- fflush(stderr);
- print_token(&recv_tok);
- }
-#endif /* GSSSASL_DEBUG */
-
- maj_stat = gsssasl_unpack_security_token(&min_stat, state->context,
- &recv_tok, &recv_mask,
- &mask_length);
-
- if (maj_stat != GSS_S_COMPLETE)
- {
- LOG_STATUS("unpacking security negotiation token", maj_stat, min_stat);
- TRACE("<== negotiate_security_options (unpack failed)");
- return -1;
+ {
+ fprintf(stderr, "Received token (size=%d)...\n",
+ recv_tok.length);
+ fflush(stderr);
+ print_token(&recv_tok);
}
+#endif /* GSSSASL_DEBUG */
+
+ maj_stat = gsssasl_unpack_security_token(&min_stat,
+ state->context,
+ &recv_tok,
+ &recv_mask,
+ &mask_length);
+
+ if (maj_stat != GSS_S_COMPLETE)
+ {
+ LOG_STATUS("unpacking security negotiation token",
+ maj_stat,
+ min_stat);
+ TRACE("<== negotiate_security_options (unpack failed)");
+ return -1;
+ }
#ifdef GSSSASL_DEBUG
- if (debug_)
- {
- fprintf(stderr, "Received security token level %d size %d\n",
- recv_mask->security_layer,
- recv_mask->token_size);
+ if (debug_)
+ {
+ fprintf(stderr, "Received security token level %d size %d\n",
+ recv_mask->security_layer,
+ recv_mask->token_size);
}
#endif
- if ((~recv_mask->security_layer) & layer)
- {
- free(recv_mask);
- TRACE("<== negotiate_security_options (unsupported security layer)");
- return -1;
- }
- mask_length =
- sizeof(recv_mask) + GSSAPI_LDAP_DN_PREFIX_LEN + strlen(state->binddn);
- send_mask = NSLDAPI_MALLOC(mask_length);
- if (send_mask == NULL)
- {
- free(recv_mask);
- TRACE("<== negotiate_security_options (malloc failed)");
- return -1;
+ if ((~recv_mask->security_layer) & layer)
+ {
+ free(recv_mask);
+ TRACE("<== negotiate_security_options (unsupported security layer)");
+ return -1;
}
- send_mask->security_layer = layer;
- send_mask->token_size = recv_mask->token_size;
- memcpy(send_mask->identity, GSSAPI_LDAP_DN_PREFIX,
- GSSAPI_LDAP_DN_PREFIX_LEN);
- memcpy(send_mask->identity + GSSAPI_LDAP_DN_PREFIX_LEN, state->binddn,
- mask_length - sizeof(recv_mask) - GSSAPI_LDAP_DN_PREFIX_LEN);
-
- free(recv_mask);
-
+ mask_length = sizeof(recv_mask) +
+ GSSAPI_LDAP_DN_PREFIX_LEN + strlen(state->binddn);
+ send_mask = NSLDAPI_MALLOC(mask_length);
+ if (send_mask == NULL)
+ {
+ free(recv_mask);
+ TRACE("<== negotiate_security_options (malloc failed)");
+ return -1;
+ }
+ send_mask->security_layer = layer;
+ send_mask->token_size = recv_mask->token_size;
+ memcpy(send_mask->identity, GSSAPI_LDAP_DN_PREFIX, GSSAPI_LDAP_DN_PREFIX_LEN);
+ memcpy(send_mask->identity + GSSAPI_LDAP_DN_PREFIX_LEN,
+ state->binddn,
+ mask_length - sizeof(recv_mask) - GSSAPI_LDAP_DN_PREFIX_LEN);
+ free(recv_mask);
+
#ifdef GSSSASL_DEBUG
- if (debug_)
- {
- fprintf(stderr, "Sending security token level %d size %d\n",
- send_mask->security_layer,
- send_mask->token_size);
- }
+ if (debug_)
+ {
+ fprintf(stderr, "Sending security token level %d size %d\n",
+ send_mask->security_layer,
+ send_mask->token_size);
+ }
#endif
- maj_stat = gsssasl_pack_security_token(&min_stat, state->context,
- send_mask, mask_length, &send_tok);
- if (maj_stat != GSS_S_COMPLETE)
- {
- LOG_STATUS("packing security negotiation token", maj_stat, min_stat);
- NSLDAPI_FREE(send_mask);
- TRACE("<== negotiate_security_options (pack failed)");
- return -1;
- }
- if ((rc = send_token(state, &send_tok)) < 0)
- {
- NSLDAPI_FREE(send_mask);
- TRACE("<== negotiate_security_options (send_token failed)");
- return rc;
+ maj_stat = gsssasl_pack_security_token(&min_stat,
+ state->context,
+ send_mask,
+ mask_length,
+ &send_tok);
+ if (maj_stat != GSS_S_COMPLETE)
+ {
+ LOG_STATUS("packing security negotiation token", maj_stat, min_stat);
+ NSLDAPI_FREE(send_mask);
+ TRACE("<== negotiate_security_options (pack failed)");
+ return -1;
+ }
+ if ((rc = send_token(state, &send_tok)) < 0)
+ {
+ NSLDAPI_FREE(send_mask);
+ TRACE("<== negotiate_security_options (send_token failed)");
+ return rc;
+ }
+ rc = parse_bind_result(state);
+
+ if (rc == 0)
+ {
+ security_context = state->context;
+ security_layer = layer;
+ security_token_size = send_mask->token_size;
}
- rc = parse_bind_result(state);
-
- if (rc == 0)
- {
- security_context = state->context;
- security_layer = layer;
- security_token_size = send_mask->token_size;
- }
- NSLDAPI_FREE(send_mask);
- if (send_tok.value != NULL)
- gss_release_buffer(&rc, &send_tok);
- if (recv_tok.value != NULL)
- gss_release_buffer(&rc, &recv_tok);
- TRACE("<== negotiate_security_options");
- return rc;
+ NSLDAPI_FREE(send_mask);
+ if (send_tok.value != NULL)
+ gss_release_buffer(&rc, &send_tok);
+ if (recv_tok.value != NULL)
+ gss_release_buffer(&rc, &recv_tok);
+ TRACE("<== negotiate_security_options");
+ return rc;
}
#ifdef GSSSASL_DEBUG
debug_ = on;
return old;
}
-#endif /* GSSSASL_DEBUG */
+#endif /* GSSSASL_DEBUG */
/*
* Public function for doing a GSS-API SASL bind
LDAP_CALL ldap_adgssapi_bind(LDAP *ld, const char *who, int layer)
{
gssldap_client_state_desc state;
- char *service_name;
- OM_uint32 min_stat;
- int rc;
- int i;
+ char *service_name;
+ OM_uint32 min_stat;
+ int rc;
+ int i;
+ struct ldap_io_fns iofns;
if (!NSLDAPI_VALID_LDAP_POINTER(ld) || ld->ld_defhost == NULL)
- return -1;
-
+ {
+ return -1;
+ }
+
for (i = 0; i < (int)strlen(ld->ld_defhost); i++)
ld->ld_defhost[i] = toupper(ld->ld_defhost[i]);
- service_name = NSLDAPI_MALLOC(sizeof(GSSAPI_LDAP_SERVICE_NAME "@") +
- strlen(ld->ld_defhost));
+ service_name =
+ NSLDAPI_MALLOC(sizeof(GSSAPI_LDAP_SERVICE_NAME "@") + strlen(ld->ld_defhost));
if (service_name == NULL)
- return -1;
-
+ {
+ return -1;
+ }
strcpy(service_name, GSSAPI_LDAP_SERVICE_NAME "@");
strcat(service_name, ld->ld_defhost);
#ifdef GSSSASL_DEBUG
- if (debug_)
- {
- fprintf(stderr, "LDAP service name: %s\n", service_name);
- fflush(stderr);
- }
+ if (debug_)
+ {
+ fprintf(stderr, "LDAP service name: %s\n", service_name);
+ fflush(stderr);
+ }
#endif
- state.msgid = -1;
- state.ld = ld;
- state.binddn = who;
- state.context = GSS_C_NO_CONTEXT;
- state.rc = LDAP_OPERATIONS_ERROR;
+ state.msgid = -1;
+ state.ld = ld;
+ state.binddn = who;
+ state.context = GSS_C_NO_CONTEXT;
+ state.rc = LDAP_OPERATIONS_ERROR;
- rc = client_establish_context(ld, &state, service_name);
- if (rc == 0)
+ rc = client_establish_context(ld, &state, service_name);
+ if (rc == 0)
+ {
rc = negotiate_security_options(&state, layer);
- if (rc == 0)
- {
+ }
+ if (rc == 0)
+ {
#ifdef GSSSASL_DEBUG
- gss_buffer_desc tname;
- gss_buffer_desc sname;
- gss_name_t targ_name;
- gss_name_t src_name;
- OM_uint32 context_flags;
- OM_uint32 lifetime;
- OM_uint32 maj_stat;
- int is_open;
- int is_local;
- gss_OID mechanism;
- gss_OID name_type;
-
- maj_stat = gss_inquire_context(&min_stat, state.context, &src_name,
- &targ_name, &lifetime, &mechanism,
- &context_flags, &is_local, &is_open);
- if (maj_stat != GSS_S_COMPLETE)
- {
- LOG_STATUS("inquiring context", maj_stat, min_stat);
- return LDAP_OPERATIONS_ERROR;
- }
- maj_stat = gss_display_name(&min_stat, src_name, &sname, &name_type);
- if (maj_stat != GSS_S_COMPLETE)
- {
- LOG_STATUS("displaying source name", maj_stat, min_stat);
- return LDAP_OPERATIONS_ERROR;
- }
- maj_stat = gss_display_name(&min_stat, targ_name, &tname,
- (gss_OID *) NULL);
- if (maj_stat != GSS_S_COMPLETE)
- {
- LOG_STATUS("displaying target name", maj_stat, min_stat);
- return LDAP_OPERATIONS_ERROR;
- }
- if (debug_)
- {
- fprintf(stderr, "\"%.*s\" to \"%.*s\", lifetime %d, flags %x, %s, %s\n",
- (int) sname.length, (char *) sname.value,
- (int) tname.length, (char *) tname.value, lifetime,
- context_flags,
- (is_local) ? "locally initiated" : "remotely initiated",
- (is_open) ? "open" : "closed");
- fflush(stderr);
- }
- (void) gss_release_name(&min_stat, &src_name);
- (void) gss_release_name(&min_stat, &targ_name);
- (void) gss_release_buffer(&min_stat, &sname);
- (void) gss_release_buffer(&min_stat, &tname);
+ gss_buffer_desc tname;
+ gss_buffer_desc sname;
+ gss_name_t targ_name;
+ gss_name_t src_name;
+ OM_uint32 context_flags;
+ OM_uint32 lifetime;
+ OM_uint32 maj_stat;
+ int is_open;
+ int is_local;
+ gss_OID mechanism;
+ gss_OID name_type;
+
+ maj_stat = gss_inquire_context(&min_stat,
+ state.context,
+ &src_name,
+ &targ_name,
+ &lifetime,
+ &mechanism,
+ &context_flags,
+ &is_local,
+ &is_open);
+ if (maj_stat != GSS_S_COMPLETE)
+ {
+ LOG_STATUS("inquiring context", maj_stat, min_stat);
+ return LDAP_OPERATIONS_ERROR;
+ }
+ maj_stat = gss_display_name(&min_stat,
+ src_name,
+ &sname,
+ &name_type);
+ if (maj_stat != GSS_S_COMPLETE)
+ {
+ LOG_STATUS("displaying source name", maj_stat, min_stat);
+ return LDAP_OPERATIONS_ERROR;
+ }
+ maj_stat = gss_display_name(&min_stat,
+ targ_name,
+ &tname,
+ (gss_OID *) NULL);
+ if (maj_stat != GSS_S_COMPLETE)
+ {
+ LOG_STATUS("displaying target name", maj_stat, min_stat);
+ return LDAP_OPERATIONS_ERROR;
+ }
+ if (debug_)
+ {
+ fprintf(stderr,
+ "\"%.*s\" to \"%.*s\", lifetime %d, flags %x, %s, %s\n",
+ (int) sname.length, (char *) sname.value,
+ (int) tname.length, (char *) tname.value, lifetime,
+ context_flags,
+ (is_local) ? "locally initiated" : "remotely initiated",
+ (is_open) ? "open" : "closed");
+ fflush(stderr);
+ }
+ (void) gss_release_name(&min_stat, &src_name);
+ (void) gss_release_name(&min_stat, &targ_name);
+ (void) gss_release_buffer(&min_stat, &sname);
+ (void) gss_release_buffer(&min_stat, &tname);
#endif
- state.rc = LDAP_SUCCESS;
- }
- NSLDAPI_FREE(service_name);
- LDAP_SET_LDERRNO(ld, state.rc, NULL, NULL);
+ state.rc = LDAP_SUCCESS;
+ }
- if (state.context != GSS_C_NO_CONTEXT)
- gss_delete_sec_context(&min_stat, &state.context, GSS_C_NO_BUFFER);
- return state.rc;
+ if (state.rc == LDAP_SUCCESS)
+ {
+ if (layer = GSSSASL_PRIVACY_PROTECTION)
+ {
+ memset(&iofns, 0, sizeof(iofns));
+ iofns.liof_read = ldap_gssapi_read;
+ iofns.liof_write = ldap_gssapi_write;
+ state.rc = ldap_set_option(ld, LDAP_OPT_IO_FN_PTRS, &iofns);
+ }
+ }
+
+ NSLDAPI_FREE(service_name);
+ LDAP_SET_LDERRNO(ld, state.rc, NULL, NULL);
+
+ return state.rc;
}
/* Wrap and encode a security negotiation token */
-unsigned long gsssasl_pack_security_token(OM_uint32 *min_stat,
- gss_ctx_id_t context,
- gsssasl_security_negotiation_t inmask,
- size_t masklength,
- gss_buffer_t wrapped_tok)
+unsigned long gsssasl_pack_security_token(OM_uint32 *min_stat,
+ gss_ctx_id_t context,
+ gsssasl_security_negotiation_t inmask,
+ size_t masklength, gss_buffer_t wrapped_tok)
{
- OM_uint32 maj_stat;
- OM_uint32 rc;
+ OM_uint32 maj_stat;
+ OM_uint32 rc;
gss_buffer_desc send_tok;
wrapped_tok->length = 0;
send_tok.length = masklength;
send_tok.value = inmask;
- maj_stat = gss_wrap(min_stat, context, 0, GSS_C_QOP_DEFAULT, &send_tok,
- (int *)&rc, wrapped_tok);
+ maj_stat = gss_wrap(min_stat,
+ context,
+ 0,
+ GSS_C_QOP_DEFAULT,
+ &send_tok,
+ (int *)&rc,
+ wrapped_tok);
inmask->token_size = ntohl(inmask->token_size);
}
/* Unwrap and decode a security negotiation token. */
-int gsssasl_unpack_security_token(OM_uint32 *min_stat, gss_ctx_id_t context,
- gss_buffer_t wrapped_tok,
- gsssasl_security_negotiation_t *outmask,
- size_t *masklength)
+int gsssasl_unpack_security_token(OM_uint32 *min_stat, gss_ctx_id_t context,
+ gss_buffer_t wrapped_tok,
+ gsssasl_security_negotiation_t *outmask,
+ size_t *masklength)
{
- OM_uint32 maj_stat;
- OM_uint32 rc;
+ OM_uint32 maj_stat;
+ OM_uint32 rc;
gss_buffer_desc recv_tok;
*masklength = 0;
*outmask = NULL;
memset(&recv_tok, '\0', sizeof(recv_tok));
- maj_stat = gss_unwrap(min_stat, context, wrapped_tok, &recv_tok,
- (int *)&rc, (gss_qop_t *) NULL);
+ maj_stat = gss_unwrap(min_stat,
+ context,
+ wrapped_tok,
+ &recv_tok,
+ (int *)&rc,
+ (gss_qop_t *) NULL);
if (maj_stat != GSS_S_COMPLETE)
return maj_stat;
+/*
#ifdef _WIN32
if (recv_tok.length < sizeof(gsssasl_security_negotiation_desc))
{
gss_release_buffer(&rc, &recv_tok);
return GSS_S_FAILURE;
}
-#endif /*WIN32*/
+#endif
+*/
- /*
- * we're lazy and don't copy the token. This could cause
- * problems if libgssapi uses a different malloc!
- */
+ /*
+ * we're lazy and don't copy the token. This could cause
+ * problems if libgssapi uses a different malloc!
+ */
*masklength = recv_tok.length;
*outmask = (gsssasl_security_negotiation_t) recv_tok.value;
if (*outmask == NULL)
int ldap_reset_principal(LDAP *ld, char *service_name, gss_name_t target_name)
{
- krb5_context context = NULL;
- krb5_principal princ;
- krb5_principal princ1;
- krb5_principal temp_princ;
- krb5_data *ptr = NULL;
- char sname = NULL;
- char *realm = NULL;
- char *server = NULL;
- char *host = NULL;
- char *cptr = NULL;
- char temp[1024];
- int i;
- int rc;
+ krb5_context context = NULL;
+ krb5_principal princ;
+ krb5_principal princ1;
+ krb5_principal temp_princ;
+ char *realm;
+ char *server_name = NULL;
+ int i;
- rc = -1;
princ = (krb5_principal)(target_name);
-
+
if (krb5_init_context(&context))
- return(rc);
- sname = strdup(service_name);
- if ((realm = strchr(sname, '@')))
- {
- *realm = '\0';
- realm++;
- }
-
- if ((cptr = strchr(sname, '/')))
- *cptr = '\0';
-
- server = strdup(realm);
- for (i = 0; i < (int)strlen(server); i++)
- server[i] = tolower(server[i]);
-
- if (princ->length != 0)
- {
- ptr = krb5_princ_component(context, princ, (princ->length - 1));
- if (ptr != NULL)
- {
- if (ptr->length != 0)
- {
- host = strdup(ptr->data);
- if ((cptr = strchr(host, '.')))
- *cptr = '\0';
- }
- }
- }
- ptr = NULL;
+ return(-1);
+
+ realm = strdup(ldap_domain_name);
+ for (i = 0; i < (int)strlen(realm); i++)
+ realm[i] = toupper(realm[i]);
+ server_name = strdup(ld->ld_defhost);
+ for (i = 0; i < (int)strlen(server_name); i++)
+ server_name[i] = tolower(server_name[i]);
- if (host != NULL)
- sprintf(temp, "%s.%s", host, server);
- else
- sprintf(temp, "%s", server);
-
temp_princ = malloc(sizeof(*princ));
memcpy(temp_princ, princ, sizeof(*princ));
- krb5_build_principal(context, &princ1, strlen(realm), realm, sname, temp,
- server, 0);
+ krb5_build_principal(context, &princ1, strlen(realm), realm, "ldap",
+ server_name, ldap_domain_name, 0);
memcpy(princ, princ1, sizeof(*princ1));
free(princ1);
krb5_free_principal(context, temp_princ);
-
-/*
- * if (host != NULL)
- * sprintf(temp, "%s/%s.%s", sname, host, server);
- * else
- * sprintf(temp, "%s/%s", sname, server);
- * rc = 0;
- */
- if (server != NULL)
- free(server);
- if (sname != NULL)
- free(sname);
- if (host != NULL)
- free(host);
+
+ if (realm != NULL)
+ free(realm);
+ if (server_name != NULL)
+ free(server_name);
if (context != NULL)
krb5_free_context(context);
- return 0;
+ return(0);
}
int ldap_delete_tickets(LDAP *ld, char *service_name)
{
- int i;
- int rc;
- krb5_context context = NULL;
- krb5_ccache v5Cache = NULL;
- krb5_creds creds;
- krb5_cc_cursor v5Cursor;
+ int i;
+ int rc;
+ krb5_context context = NULL;
+ krb5_ccache v5Cache = NULL;
+ krb5_creds creds;
+ krb5_cc_cursor v5Cursor;
krb5_error_code code;
- char *sServerName;
+ char *sServerName;
if (!NSLDAPI_VALID_LDAP_POINTER(ld) || ld->ld_defhost == NULL)
- return -1;
+ {
+ return -1;
+ }
for (i = 0; i < (int)strlen(ld->ld_defhost); i++)
ld->ld_defhost[i] = toupper(ld->ld_defhost[i]);
while (!(code = krb5_cc_next_cred(context, v5Cache, &v5Cursor, &creds)))
{
if (krb5_unparse_name(context, creds.server, &sServerName))
- {
- krb5_free_cred_contents(context, &creds);
- continue;
- }
+ {
+ krb5_free_cred_contents(context, &creds);
+ continue;
+ }
if (!memcmp(sServerName, service_name, strlen(service_name)))
- krb5_cc_remove_cred(context, v5Cache, 0, &creds);
+ {
+ krb5_cc_remove_cred(context, v5Cache, 0, &creds);
+ }
continue;
}
-
+
if ((code == KRB5_CC_END) || (code == KRB5_CC_NOTFOUND))
- krb5_cc_end_seq_get(context, v5Cache, &v5Cursor);
+ {
+ krb5_cc_end_seq_get(context, v5Cache, &v5Cursor);
+ }
rc = 0;
cleanup:
krb5_free_context(context);
return(rc);
}
+
+int locate_ldap_server(char *domain, char **server_name)
+{
+ char service[128];
+ char host[128];
+ int location_type;
+ int length;
+ int rc;
+ int return_code;
+ int entry_length;
+ int server_count;
+ unsigned char reply[1024];
+ unsigned char *ptr;
+
+ strcpy(ldap_domain_name, domain);
+ sprintf(service, "%s.%s.%s.", LDAP_SERVICE, TCP_PROTOCOL, domain);
+
+ return_code = -1;
+ server_count = 0;
+ memset(reply, '\0', sizeof(reply));
+ length = res_search(service, C_IN, T_SRV, reply, sizeof(reply));
+ if (length >= 0)
+ {
+ ptr = reply;
+ ptr += sizeof(HEADER);
+ if ((rc = dn_expand(reply, reply + length, ptr, host,
+ sizeof(host))) < 0)
+ return(-1);
+ ptr += (rc + 4);
+
+ while (ptr < reply + length)
+ {
+ if ((rc = dn_expand(reply, reply + length, ptr, host,
+ sizeof(host))) < 0)
+ break;
+ ptr += rc;
+ location_type = (ptr[0] << 8) | ptr[1];
+ ptr += 8;
+ entry_length = (ptr[0] << 8) | ptr[1];
+ ptr += 2;
+ if (location_type == T_SRV)
+ {
+ if ((rc = dn_expand(reply, reply + length, ptr + 6, host,
+ sizeof(host))) < 0)
+ return -1;
+
+ (*server_name) = strdup(host);
+ ++server_name;
+ return_code = 1;
+ server_count++;
+ }
+ ptr += entry_length;
+ }
+ }
+ return(return_code);
+}
--- /dev/null
+/*--
+
+THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
+ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
+TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
+PARTICULAR PURPOSE.
+
+Copyright (C) 1999 Microsoft Corporation. All rights reserved.
+
+Module Name:
+
+ ksetpw.c
+
+Abstract:
+
+ Set a user's password using the
+ Kerberos Change Password Protocol (I-D) variant for Windows 2000
+
+--*/
+/*
+ * lib/krb5/os/changepw.c
+ *
+ * Copyright 1990 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ */
+
+#define NEED_SOCKETS
+#include <krb5.h>
+#include <krb.h>
+#ifdef _WIN32
+#include "k5-int.h"
+#include "adm_err.h"
+#include "krb5_err.h"
+#endif
+#include <auth_con.h>
+#include "kpasswd.h"
+
+#ifndef _WIN32
+#include <sys/socket.h>
+#include <netdb.h>
+#include <sys/select.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <sys/timeb.h>
+#include <errno.h>
+
+
+#define PW_LENGTH 25
+
+#ifndef krb5_is_krb_error
+#define krb5_is_krb_error(dat)\
+ ((dat) && (dat)->length && ((dat)->data[0] == 0x7e ||\
+ (dat)->data[0] == 0x5e))
+#endif
+
+/* Win32 defines. */
+#if defined(_WIN32) && !defined(__CYGWIN32__)
+#ifndef ECONNABORTED
+#define ECONNABORTED WSAECONNABORTED
+#endif
+#ifndef ECONNREFUSED
+#define ECONNREFUSED WSAECONNREFUSED
+#endif
+#ifndef EHOSTUNREACH
+#define EHOSTUNREACH WSAEHOSTUNREACH
+#endif
+#endif /* _WIN32 && !__CYGWIN32__ */
+
+static const char rcsid[] = "$Id$";
+
+static int frequency[26][26] =
+{ {4, 20, 28, 52, 2, 11, 28, 4, 32, 4, 6, 62, 23, 167, 2, 14, 0, 83, 76,
+127, 7, 25, 8, 1, 9, 1}, /* aa - az */
+ {13, 0, 0, 0, 55, 0, 0, 0, 8, 2, 0, 22, 0, 0, 11, 0, 0, 15, 4, 2, 13, 0,
+0, 0, 15, 0}, /* ba - bz */
+ {32, 0, 7, 1, 69, 0, 0, 33, 17, 0, 10, 9, 1, 0, 50, 3, 0, 10, 0, 28, 11,
+0, 0, 0, 3, 0}, /* ca - cz */
+ {40, 16, 9, 5, 65, 18, 3, 9, 56, 0, 1, 4, 15, 6, 16, 4, 0, 21, 18, 53,
+19, 5, 15, 0, 3, 0}, /* da - dz */
+ {84, 20, 55, 125, 51, 40, 19, 16, 50, 1, 4, 55, 54, 146, 35, 37, 6, 191,
+149, 65, 9, 26, 21, 12, 5, 0}, /* ea - ez */
+ {19, 3, 5, 1, 19, 21, 1, 3, 30, 2, 0, 11, 1, 0, 51, 0, 0, 26, 8, 47, 6,
+3, 3, 0, 2, 0}, /* fa - fz */
+ {20, 4, 3, 2, 35, 1, 3, 15, 18, 0, 0, 5, 1, 4, 21, 1, 1, 20, 9, 21, 9,
+0, 5, 0, 1, 0}, /* ga - gz */
+ {101, 1, 3, 0, 270, 5, 1, 6, 57, 0, 0, 0, 3, 2, 44, 1, 0, 3, 10, 18, 6,
+0, 5, 0, 3, 0}, /* ha - hz */
+ {40, 7, 51, 23, 25, 9, 11, 3, 0, 0, 2, 38, 25, 202, 56, 12, 1, 46, 79,
+117, 1, 22, 0, 4, 0, 3}, /* ia - iz */
+ {3, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 3, 0, 0, 0,
+0, 0}, /* ja - jz */
+ {1, 0, 0, 0, 11, 0, 0, 0, 13, 0, 0, 0, 0, 2, 0, 0, 0, 0, 6, 2, 1, 0, 2,
+0, 1, 0}, /* ka - kz */
+ {44, 2, 5, 12, 62, 7, 5, 2, 42, 1, 1, 53, 2, 2, 25, 1, 1, 2, 16, 23, 9,
+0, 1, 0, 33, 0}, /* la - lz */
+ {52, 14, 1, 0, 64, 0, 0, 3, 37, 0, 0, 0, 7, 1, 17, 18, 1, 2, 12, 3, 8,
+0, 1, 0, 2, 0}, /* ma - mz */
+ {42, 10, 47, 122, 63, 19, 106, 12, 30, 1, 6, 6, 9, 7, 54, 7, 1, 7, 44,
+124, 6, 1, 15, 0, 12, 0}, /* na - nz */
+ {7, 12, 14, 17, 5, 95, 3, 5, 14, 0, 0, 19, 41, 134, 13, 23, 0, 91, 23,
+42, 55, 16, 28, 0, 4, 1}, /* oa - oz */
+ {19, 1, 0, 0, 37, 0, 0, 4, 8, 0, 0, 15, 1, 0, 27, 9, 0, 33, 14, 7, 6, 0,
+0, 0, 0, 0}, /* pa - pz */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0,
+0, 0, 0}, /* qa - qz */
+ {83, 8, 16, 23, 169, 4, 8, 8, 77, 1, 10, 5, 26, 16, 60, 4, 0, 24, 37,
+55, 6, 11, 4, 0, 28, 0}, /* ra - rz */
+ {65, 9, 17, 9, 73, 13, 1, 47, 75, 3, 0, 7, 11, 12, 56, 17, 6, 9, 48,
+116, 35, 1, 28, 0, 4, 0}, /* sa - sz */
+ {57, 22, 3, 1, 76, 5, 2, 330, 126, 1, 0, 14, 10, 6, 79, 7, 0, 49, 50,
+56, 21, 2, 27, 0, 24, 0}, /* ta - tz */
+ {11, 5, 9, 6, 9, 1, 6, 0, 9, 0, 1, 19, 5, 31, 1, 15, 0, 47, 39, 31, 0,
+3, 0, 0, 0, 0}, /* ua - uz */
+ {7, 0, 0, 0, 72, 0, 0, 0, 28, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 3, 0}, /* va - vz */
+ {36, 1, 1, 0, 38, 0, 0, 33, 36, 0, 0, 4, 1, 8, 15, 0, 0, 0, 4, 2, 0, 0,
+1, 0, 0, 0}, /* wa - wz */
+ {1, 0, 2, 0, 0, 1, 0, 0, 3, 0, 0, 0, 0, 0, 1, 5, 0, 0, 0, 3, 0, 0, 1, 0,
+0, 0}, /* xa - xz */
+ {14, 5, 4, 2, 7, 12, 12, 6, 10, 0, 0, 3, 7, 5, 17, 3, 0, 4, 16, 30, 0,
+0, 5, 0, 0, 0}, /* ya - yz */
+ {1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0}}; /* za - zz */
+
+/*
+ * This MUST be equal to the sum of the equivalent rows above.
+ */
+
+static int row_sums[26] =
+{796, 160, 284, 401, 1276, 262, 199, 539, 777,
+ 16, 39, 351, 243, 751, 662, 181, 17, 683,
+ 662, 968, 248, 115, 180, 17, 162, 5};
+
+/*
+ * Frequencies of starting characters
+ */
+
+static int start_freq [26] =
+{1299, 425, 725, 271, 375, 470, 93, 223, 1009,
+ 24, 20, 355, 379, 319, 823, 618, 21, 317,
+ 962, 1991, 271, 104, 516, 6, 16, 14};
+
+/*
+ * This MUST be equal to the sum of all elements in the above array.
+ */
+static int total_sum = 11646;
+
+long myrandom();
+void generate_password(char *password);
+int set_password(char *user, char *domain);
+krb5_error_code encode_krb5_setpw
+ PROTOTYPE((const krb5_setpw *rep, krb5_data ** code));
+krb5_error_code
+krb5_locate_kpasswd(krb5_context context, const krb5_data *realm,
+ struct sockaddr **addr_pp, int *naddrs);
+
+krb5_error_code krb5_mk_setpw_req(krb5_context context, krb5_auth_context auth_context,
+ krb5_data *ap_req, krb5_principal targprinc,
+ char *passwd, krb5_data *packet)
+{
+ krb5_error_code ret;
+ krb5_setpw setpw;
+ krb5_data cipherpw;
+ krb5_data *encoded_setpw;
+ krb5_replay_data replay;
+ char *ptr;
+ register int count = 2;
+
+ memset (&setpw, 0, sizeof(krb5_setpw));
+ if (ret = krb5_auth_con_setflags(context, auth_context,
+ KRB5_AUTH_CONTEXT_DO_SEQUENCE))
+ return(ret);
+ setpw.targprinc = targprinc;
+ setpw.newpasswd.length = strlen(passwd);
+ setpw.newpasswd.data = passwd;
+ if ((ret = encode_krb5_setpw(&setpw, &encoded_setpw)))
+ return( ret );
+ if (ret = krb5_mk_priv(context, auth_context,
+ encoded_setpw, &cipherpw, &replay))
+ return(ret);
+ packet->length = 6 + ap_req->length + cipherpw.length;
+ packet->data = (char *) malloc(packet->length);
+ ptr = packet->data;
+ /* Length */
+ *ptr++ = (packet->length>>8) & 0xff;
+ *ptr++ = packet->length & 0xff;
+ /* version */
+ *ptr++ = (char)0xff;
+ *ptr++ = (char)0x80;
+ /* ap_req length, big-endian */
+ *ptr++ = (ap_req->length>>8) & 0xff;
+ *ptr++ = ap_req->length & 0xff;
+ /* ap-req data */
+ memcpy(ptr, ap_req->data, ap_req->length);
+ ptr += ap_req->length;
+ /* krb-priv of password */
+ memcpy(ptr, cipherpw.data, cipherpw.length);
+ return(0);
+}
+
+krb5_error_code krb5_rd_setpw_rep(krb5_context context, krb5_auth_context auth_context,
+ krb5_data *packet, int *result_code,
+ krb5_data *result_data)
+{
+ char *ptr;
+ int plen;
+ int vno;
+ krb5_data ap_rep;
+ krb5_error_code ret;
+ krb5_data cipherresult;
+ 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)
+ return(KRB5KRB_AP_ERR_MODIFIED);
+ ptr = packet->data;
+ if (krb5_is_krb_error(packet))
+ {
+ ret = decode_krb5_error(packet, &krberror);
+ if (ret)
+ return(ret);
+ ret = krberror->error;
+ krb5_free_error(context, krberror);
+ return(ret);
+ }
+ /* verify length */
+ plen = (*ptr++ & 0xff);
+ plen = (plen<<8) | (*ptr++ & 0xff);
+ if (plen != packet->length)
+ return(KRB5KRB_AP_ERR_MODIFIED);
+ vno = (*ptr++ & 0xff);
+ vno = (vno<<8) | (*ptr++ & 0xff);
+ if (vno != KRB5_KPASSWD_VERS_SETPW && vno != KRB5_KPASSWD_VERS_CHANGEPW)
+ return(KRB5KDC_ERR_BAD_PVNO);
+ /* read, check ap-rep length */
+ ap_rep.length = (*ptr++ & 0xff);
+ ap_rep.length = (ap_rep.length<<8) | (*ptr++ & 0xff);
+ if (ptr + ap_rep.length >= packet->data + packet->length)
+ return(KRB5KRB_AP_ERR_MODIFIED);
+ if (ap_rep.length)
+ {
+ /* verify ap_rep */
+ ap_rep.data = ptr;
+ ptr += ap_rep.length;
+ if (ret = krb5_rd_rep(context, auth_context, &ap_rep, &ap_rep_enc))
+ return(ret);
+ krb5_free_ap_rep_enc_part(context, ap_rep_enc);
+ /* extract and decrypt the result */
+ cipherresult.data = ptr;
+ cipherresult.length = (packet->data + packet->length) - ptr;
+ /* 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);
+ }
+ else
+ {
+ cipherresult.data = ptr;
+ cipherresult.length = (packet->data + packet->length) - ptr;
+
+ if (ret = krb5_rd_error(context, &cipherresult, &krberror))
+ return(ret);
+
+ clearresult = krberror->e_data;
+ }
+ if (clearresult.length < 2)
+ {
+ ret = KRB5KRB_AP_ERR_MODIFIED;
+ goto cleanup;
+ }
+ ptr = clearresult.data;
+ *result_code = (*ptr++ & 0xff);
+ *result_code = (*result_code<<8) | (*ptr++ & 0xff);
+ if ((*result_code < KRB5_KPASSWD_SUCCESS) ||
+ (*result_code > KRB5_KPASSWD_ACCESSDENIED))
+ {
+ ret = KRB5KRB_AP_ERR_MODIFIED;
+ goto cleanup;
+ }
+ /* all success replies should be authenticated/encrypted */
+ if ((ap_rep.length == 0) && (*result_code == KRB5_KPASSWD_SUCCESS))
+ {
+ ret = KRB5KRB_AP_ERR_MODIFIED;
+ goto cleanup;
+ }
+ result_data->length = (clearresult.data + clearresult.length) - ptr;
+ if (result_data->length)
+ {
+ result_data->data = (char *) malloc(result_data->length);
+ memcpy(result_data->data, ptr, result_data->length);
+ }
+ else
+ result_data->data = NULL;
+ ret = 0;
+cleanup:
+ if (ap_rep.length)
+ free(clearresult.data);
+ else
+ krb5_free_error(context, krberror);
+ return(ret);
+}
+
+krb5_error_code krb5_set_password(krb5_context context, krb5_ccache ccache,
+ char *newpw, char *user, char *domain,
+ int *result_code)
+{
+ krb5_auth_context auth_context;
+ krb5_data ap_req;
+ krb5_data chpw_req;
+ krb5_data chpw_rep;
+ krb5_data result_string;
+ krb5_address local_kaddr;
+ krb5_address remote_kaddr;
+ char userrealm[256];
+ char temp[256];
+ krb5_error_code code;
+ krb5_creds creds;
+ krb5_creds *credsp;
+ struct sockaddr *addr_p;
+ struct sockaddr local_addr;
+ struct sockaddr remote_addr;
+ struct sockaddr tmp_addr;
+ SOCKET s1;
+ SOCKET s2;
+ int i;
+ int out;
+ int addrlen;
+ int cc;
+ int local_result_code;
+ int tmp_len;
+ int error_count;
+ krb5_principal targprinc;
+ struct timeval TimeVal;
+ fd_set readfds;
+
+ auth_context = NULL;
+ addr_p = NULL;
+ credsp = NULL;
+ memset(&local_addr, 0, sizeof(local_addr));
+ memset(&local_kaddr, 0, sizeof(local_kaddr));
+ memset(&result_string, 0, sizeof(result_string));
+ memset(&remote_kaddr, 0, sizeof(remote_kaddr));
+ memset(&chpw_req, 0, sizeof(krb5_data));
+ memset(&chpw_rep, 0, sizeof(krb5_data));
+ memset(&ap_req, 0, sizeof(krb5_data));
+ auth_context = NULL;
+ memset(&creds, 0, sizeof(creds));
+ memset(userrealm, '\0', sizeof(userrealm));
+ targprinc = NULL;
+ for (i = 0; i < (int)strlen(domain); i++)
+ userrealm[i] = toupper(domain[i]);
+
+ sprintf(temp, "%s@%s", user, userrealm);
+ krb5_parse_name(context, temp, &targprinc);
+
+ sprintf(temp, "%s@%s", "kadmin/changepw", userrealm);
+ if (code = krb5_parse_name(context, temp, &creds.server))
+ goto cleanup;
+
+ if (code = krb5_cc_get_principal(context, ccache, &creds.client))
+ goto cleanup;
+ if (code = krb5_get_credentials(context, 0, ccache, &creds, &credsp))
+ goto cleanup;
+ if (code = krb5_mk_req_extended(context, &auth_context, AP_OPTS_USE_SUBKEY,
+ NULL, credsp, &ap_req))
+ goto cleanup;
+ if (code = krb5_locate_kpasswd(context, &targprinc->realm, &addr_p, &out))
+ goto cleanup;
+ if (out == 0)
+ { /* Couldn't resolve any KPASSWD names */
+ code = 1;
+ goto cleanup;
+ }
+
+ /* this is really obscure. s1 is used for all communications. it
+ is left unconnected in case the server is multihomed and routes
+ are asymmetric. s2 is connected to resolve routes and get
+ addresses. this is the *only* way to get proper addresses for
+ multihomed hosts if routing is asymmetric.
+
+ A related problem in the server, but not the client, is that
+ many os's have no way to disconnect a connected udp socket, so
+ the s2 socket needs to be closed and recreated for each
+ request. The s1 socket must not be closed, or else queued
+ requests will be lost.
+
+ A "naive" client implementation (one socket, no connect,
+ hostname resolution to get the local ip addr) will work and
+ interoperate if the client is single-homed. */
+
+ if ((s1 = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET)
+ {
+ free(addr_p);
+ return(errno);
+ }
+ if ((s2 = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET)
+ {
+ closesocket(s1);
+ free(addr_p);
+ return(errno);
+ }
+ error_count = 0;
+ for (i=0; i<out; i++)
+ {
+ if (connect(s2, &addr_p[i], sizeof(addr_p[i])) == SOCKET_ERROR)
+ continue;
+
+ addrlen = sizeof(local_addr);
+ if (getsockname(s2, &local_addr, &addrlen) < 0)
+ continue;
+ if (((struct sockaddr_in *)&local_addr)->sin_addr.s_addr != 0)
+ {
+ 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);
+ }
+ else
+ {
+ krb5_address **addrs;
+ krb5_os_localaddr(context, &addrs);
+ local_kaddr.magic = addrs[0]->magic;
+ local_kaddr.addrtype = addrs[0]->addrtype;
+ local_kaddr.length = addrs[0]->length;
+ local_kaddr.contents = calloc(1, addrs[0]->length);
+ memcpy(local_kaddr.contents, addrs[0]->contents, addrs[0]->length);
+ krb5_free_addresses(context, addrs);
+ }
+
+ addrlen = sizeof(remote_addr);
+ if (getpeername(s2, &remote_addr, &addrlen) < 0)
+ continue;
+ 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);
+ /* mk_priv requires that the local address be set.
+ getsockname is used for this. rd_priv requires that the
+ remote address be set. recvfrom is used for this. If
+ rd_priv is given a local address, and the message has the
+ recipient addr in it, this will be checked. However, there
+ is simply no way to know ahead of time what address the
+ message will be delivered *to*. Therefore, it is important
+ that either no recipient address is in the messages when
+ mk_priv is called, or that no local address is passed to
+ rd_priv. Both is a better idea, and I have done that. In
+ summary, when mk_priv is called, *only* a local address is
+ specified. when rd_priv is called, *only* a remote address
+ is specified. Are we having fun yet? */
+ if (code = krb5_auth_con_setaddrs(context, auth_context, &local_kaddr, NULL))
+ goto cleanup;
+ if (code = krb5_mk_setpw_req(context, auth_context, &ap_req,
+ targprinc, newpw, &chpw_req))
+ goto cleanup;
+ if ((cc = sendto(s1, chpw_req.data, chpw_req.length, 0,
+ (struct sockaddr *) &addr_p[i],
+ sizeof(addr_p[i]))) != chpw_req.length)
+ continue; /* try the next addr */
+#ifdef _WIN32
+ krb5_free_data_contents(context, &chpw_req);
+#else
+ free(chpw_req.data);
+#endif
+ chpw_rep.length = 1500;
+ chpw_rep.data = (char *) calloc(1, chpw_rep.length);
+ /* XXX need a timeout/retry loop here */
+ /* "recv" would be good enough here... except that Windows/NT
+ commits the atrocity of returning -1 to indicate failure,
+ but leaving errno set to 0.
+
+ "recvfrom(...,NULL,NULL)" would seem to be a good enough
+ alternative, and it works on NT, but it doesn't work on
+ SunOS 4.1.4 or Irix 5.3. Thus we must actually accept the
+ value and discard it. */
+ tmp_len = sizeof(tmp_addr);
+ TimeVal.tv_sec = 10;
+ TimeVal.tv_usec = 0;
+
+ FD_ZERO(&readfds);
+ FD_SET(s1, &readfds);
+ code = select(1, &readfds, NULL, NULL, &TimeVal);
+
+ if ((code == 0) || (code == SOCKET_ERROR))
+ {
+ if (error_count < 2)
+ {
+ closesocket(s1);
+ closesocket(s2);
+ if ((s1 = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET)
+ goto cleanup;
+ if ((s2 = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET)
+ goto cleanup;
+ ++error_count;
+ --i;
+ continue;
+ }
+ code = errno;
+ goto cleanup;
+ }
+ if ((cc = recvfrom(s1, chpw_rep.data, chpw_rep.length, 0, &tmp_addr, &tmp_len)) < 0)
+ {
+ code = errno;
+ goto cleanup;
+ }
+ chpw_rep.length = cc;
+ if (code = krb5_auth_con_setaddrs(context, auth_context, NULL,
+ &remote_kaddr))
+ {
+ goto cleanup;
+ }
+ local_result_code = 0;
+ code = krb5_rd_setpw_rep(context, auth_context, &chpw_rep,
+ &local_result_code, &result_string);
+
+ if (result_code)
+ *result_code = local_result_code;
+#ifdef _WIN32
+ krb5_free_data_contents(context, &chpw_req);
+#else
+ free(chpw_req.data);
+#endif
+ break;
+
+ }
+cleanup:
+ closesocket(s1);
+ closesocket(s2);
+ if (addr_p != NULL)
+ free(addr_p);
+ if (auth_context != NULL)
+ krb5_auth_con_free(context, auth_context);
+ if (ap_req.data != NULL)
+#ifdef _WIN32
+ krb5_free_data_contents(context, &ap_req);
+#else
+ free(ap_req.data);
+#endif
+ krb5_free_cred_contents(context, &creds);
+ if (credsp != NULL)
+ krb5_free_creds(context, credsp);
+ if (targprinc != NULL)
+ krb5_free_principal(context, targprinc);
+ return(code);
+}
+
+int set_password(char *user, char *domain)
+{
+ krb5_context context;
+ krb5_ccache ccache;
+ int res_code;
+ krb5_error_code retval;
+ char pw[PW_LENGTH+1];
+
+ if (retval = krb5_init_context(&context))
+ return retval;
+ if (retval = krb5_cc_default(context, &ccache))
+ return(retval);
+
+ memset(pw, '\0', sizeof(pw));
+ generate_password(pw);
+ retval = krb5_set_password(context, ccache, pw, user, domain, &res_code);
+
+ krb5_cc_close(context, ccache);
+ krb5_free_context(context);
+ return(retval);
+}
+
+void generate_password(char *password)
+{
+ int i;
+ int j;
+ int row_position;
+ int nchars;
+ int position;
+ int word;
+ int line;
+ char *pwp;
+
+ for (line = 22; line; --line)
+ {
+ for (word = 7; word; --word)
+ {
+ position = myrandom()%total_sum;
+ for(row_position = 0, j = 0; position >= row_position; row_position += start_freq[j], j++)
+ continue;
+ *(pwp = password) = j + 'a' - 1;
+ for (nchars = PW_LENGTH-1; nchars; --nchars)
+ {
+ i = *pwp - 'a';
+ pwp++;
+ position = myrandom()%row_sums[i];
+ for (row_position = 0, j = 0; position >= row_position; row_position += frequency[i][j], j++)
+ continue;
+ *pwp = j + 'a' - 1;
+ }
+ *(++pwp)='\0';
+ return;
+ }
+ putchar('\n');
+ }
+}
+
+long myrandom()
+{
+ static int init = 0;
+ int pid;
+#ifdef _WIN32
+ struct _timeb timebuffer;
+#else
+ struct timeval tv;
+#endif
+
+ if (!init)
+ {
+ init = 1;
+ pid = getpid();
+#ifdef _WIN32
+ _ftime(&timebuffer);
+ srand(timebuffer.time ^ timebuffer.millitm ^ pid);
+#else
+ gettimeofday(&tv, (struct timezone *) NULL);
+ srandom(tv.tv_sec ^ tv.tv_usec ^ pid);
+#endif
+ }
+ return (rand());
+}
/* $Header$
- *
- * Do incremental updates of a Windows Active Directory
+/*test parameters for reactivating a user account - done
+ * users 9 9 aadam 1 sh account test A 1 3 2 aadam 1 csh new login b 1 2 3
*
- * test parameters for reactivating a user account
- * users 9 9 testaccount 1 sh account test A 3 2 3 testaccount 1 csh new login b 1 2 3
- */
-
+ * test parameters for deactivating a user account - done
+ * users 9 9 aadam 0 sh account test A 1 2 3 aadam 1 csh new login b 0 0 0
+ *
+ *test parameters for creating a user account - done
+ * users 9 9 aadam 1 sh account test A 0 0 0 aadam 1 csh new login b 1 2 3
+ *
+ * test parameters for deleting a group - done
+ * list 7 7 pismere-team 1 2 3 4 5 6 pismere-team 8 9 10 11 12 0
+ *
+ * test parameters for creating and populating a group - done
+ * list 7 7 pismere-team 2 2 3 4 5 0 pismere-team 1 9 10 11 12 13
+ *
+ * test parameters for renaming a group - done
+ * list 7 7 testgroup 1 2 3 4 5 6 pismere-team 1 9 10 11 12 13
+ *
+ * test parameters for creating and not populating a group - done
+ * list 0 7 pismere-team 1 9 10 11 12 13
+ *
+ * test parameters for add member to list - done
+ * imembers 9 9 pismere-team USER dtanner 0 2 3 4 5 6 pismere-team USER dtanner 1 2 3 4 5 6
+ * note: the group the group will be created if it does not exist in the AD.
+ *
+ * test parameters for remove member from list - done
+ * imembers 9 0 pismere-team USER testaccount 1 2 3 4 5 6
+ *
+ * test parameters for changing account name - done
+ * users 9 9 aatestaccount 1 sh account test A 1 1 2 darkwing 1 csh new login b 1 2 3
+ *
+*/
#include <mit-copyright.h>
#ifdef _WIN32
#include <windows.h>
#include <malloc.h>
#include <lmaccess.h>
#endif
+
+#include <string.h>
#include <ldap.h>
#include <stdio.h>
#include <moira.h>
#include <moira_site.h>
+#include <mrclient.h>
#include <krb5.h>
#include <krb.h>
#include <gsssasl.h>
#include <gssldap.h>
+#include "kpasswd.h"
+
+#ifdef _WIN32
+#ifndef ECONNABORTED
+#define ECONNABORTED WSAECONNABORTED
+#endif
+#ifndef ECONNREFUSED
+#define ECONNREFUSED WSAECONNREFUSED
+#endif
+#ifndef EHOSTUNREACH
+#define EHOSTUNREACH WSAEHOSTUNREACH
+#endif
+#define krb5_xfree free
+#endif /* _WIN32 */
#ifndef _WIN32
#include <sys/utsname.h>
+#define UCHAR unsigned char
+
#define UF_SCRIPT 0x0001
#define UF_ACCOUNTDISABLE 0x0002
#define UF_HOMEDIR_REQUIRED 0x0008
#define UF_LOCKOUT 0x0010
#define UF_PASSWD_NOTREQD 0x0020
#define UF_PASSWD_CANT_CHANGE 0x0040
+#define UF_DONT_EXPIRE_PASSWD 0x10000
#define UF_TEMP_DUPLICATE_ACCOUNT 0x0100
#define UF_NORMAL_ACCOUNT 0x0200
} SID;
#endif/*!WIN32*/
+#define ADS_GROUP_TYPE_GLOBAL_GROUP 0x00000002
+#define ADS_GROUP_TYPE_DOMAIN_LOCAL_GROUP 0x00000004
+#define ADS_GROUP_TYPE_LOCAL_GROUP 0x00000004
+#define ADS_GROUP_TYPE_UNIVERSAL_GROUP 0x00000008
+#define ADS_GROUP_TYPE_SECURITY_ENABLED 0x80000000
+
+#define QUERY_VERSION -1
+#define PRIMARY_REALM "ATHENA.MIT.EDU"
+
#define SUBSTITUTE 1
#define REPLACE 2
+#define USERS 0
+#define GROUPS 1
+
#define MEMBER_ADD 1
#define MEMBER_REMOVE 2
#define MEMBER_CHANGE_NAME 3
#define MEMBER_ACTIVATE 4
#define MEMBER_DEACTIVATE 5
+#define MEMBER_CREATE 6
#define GROUP_CREATE 1
#define GROUP_DELETE 2
} LK_ENTRY;
#define LDAP_BERVAL struct berval
+#define MAX_SERVER_NAMES 32
+
+#define ADD_ATTR(t, v, o) \
+ mods[n] = malloc(sizeof(LDAPMod)); \
+ mods[n]->mod_op = o; \
+ mods[n]->mod_type = t; \
+ mods[n++]->mod_values = v
LK_ENTRY *member_base = NULL;
-char group_ou[] = "OU=groups,OU=athena";
+LK_ENTRY *sid_base = NULL;
+LK_ENTRY **sid_ptr = NULL;
+char kerberos_ou[] = "OU=kerberos, OU=moira, OU=athena";
+char contact_ou[] = "OU=strings, OU=moira, OU=athena";
+char user_ou[] = "OU=users, OU=moira, OU=athena";
+char group_ou_distribution[] = "OU=distribution, OU=lists, OU=moira, OU=athena";
+char group_ou_security[] = "OU=security, OU=lists, OU=moira, OU=athena";
+char group_ou_neither[] = "OU=neither, OU=lists, OU=moira, OU=athena";
+char group_ou_both[] = "OU=both, OU=lists, OU=moira, OU=athena";
+char group_ou_root[] = "OU=lists, OU=moira, OU=athena";
char *whoami;
-static int mr_connections = 0;
-
-int add_list_members(int ac, char **av, void *group);
-int add_user_lists(int ac, char **av, void *user);
-int member_update(LDAP *ldap_handle, char *dn_path, LDAPMessage *ldap_entry,
- char *login_name, char *new_login_name, char *ldap_hostname,
- int operation, LK_ENTRY *group_base);
-int group_update(LDAP *ldap_handle, char *ldap_hostname,
- char *before_group_name, char *after_group_name,
- int operation, LK_ENTRY *user_list);
-int check_user(int ac, char **av, void *ustate);
-int construct_newvalues(LK_ENTRY *linklist_base, int modvalue_count,
- int newValue_count, char *oldValue, char *newValue,
- LDAPMod ***newValueArray, char ****modvalues,
- int type);
-int convert_domain_to_dn(char *domain, char **bind_path);
-void delete_user(LDAP *ldap_handle, LDAPMessage *ldap_entry);
+char group_manager[64];
+char ldap_domain[256];
+char list_type[32];
+char GroupType[2];
+int maillist_flag;
+int group_flag;
+int mr_connections = 0;
+
+extern int locate_ldap_server(char *domain, char *server_name[]);
+extern int set_password(char *user, char *domain);
+
+int user_create(int ac, char **av, void *ptr);
+int user_change_status(LDAP *ldap_handle, char *dn_path,
+ char *u_name, int operation);
+int user_delete(LDAP *ldap_handle, char *dn_path, char *u_name);
+int contact_create(LDAP *ld, char *bind_path, char *user, char *group_ou);
+int get_group_info(int ac, char**av, void *ptr);
+int group_create(int ac, char **av, void *ptr);
+int group_delete(int ac, char **av, void *ptr);
+int group_ad_delete(LDAP *ldap_handle, char *dn_path, char *group_name);
+int group_list_build(int ac, char **av, void *ptr);
+int group_update_membership(LDAP *ldap_handle, char *dn_path, char *group_name);
+int member_list_build(int ac, char **av, void *ptr);
+int member_list_process(LDAP *ldap_handle, char *dn_path, char *group_name,
+ char *group_ou, char *group_membership);
+int sid_update(LDAP *ldap_handle, char *dn_path);
+int check_string(char *s);
+void convert_b_to_a(char *string, UCHAR *binary, int length);
+int mr_connect_cl(char *server, char *client, int version, int auth);
+
void do_list(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
- char **before, int beforec, char **after, int afterc);
+ char **before, int beforec, char **after, int afterc);
void do_user(LDAP *ldap_handle, LDAPMessage *ldap_entry, char *ldap_hostname,
- char *dn_path, char **before, int beforec, char **after,
- int afterc);
+ char *dn_path, char **before, int beforec, char **after,
+ int afterc);
void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
- char **before, int beforec, char **after, int afterc);
-void edit_group(int op, char *group, char *type, char *member,
- LDAP *ldap_handle, char *dn_path, char *ldap_hostname);
-int linklist_create_entry(char *attribute, char *value,
- LK_ENTRY **linklist_entry);
+ char **before, int beforec, char **after, int afterc);
+int linklist_create_entry(char *attribute, char *value,
+ LK_ENTRY **linklist_entry);
int linklist_build(LDAP *ldap_handle, char *dn_path, char *search_exp,
- char **attr_array, LK_ENTRY **linklist_base,
- int *linklist_count);
+ char **attr_array, LK_ENTRY **linklist_base,
+ int *linklist_count);
void linklist_free(LK_ENTRY *linklist_base);
-void free_values(int newvalue_count, LDAPMod **newvalue_array,
- char ***modvalues);
+
+int retrieve_attributes(LDAP *ldap_handle, LDAPMessage *ldap_entry,
+ char *distinguished_name, LK_ENTRY **linklist_current);
+int retrieve_entries(LDAP *ldap_handle, LDAPMessage *ldap_entry,
+ LK_ENTRY **linklist_base, int *linklist_count);
+int retrieve_values(LDAP *ldap_handle, LDAPMessage *ldap_entry,
+ char *Attribute, char *distinguished_name,
+ LK_ENTRY **linklist_current);
+
+int construct_newvalues(LK_ENTRY *linklist_base, int modvalue_count,
+ char *oldValue, char *newValue,
+ char ***modvalues, int type);
+void free_values(char **modvalues);
+
+int convert_domain_to_dn(char *domain, char **bind_path);
void get_distinguished_name(LDAP *ldap_handle, LDAPMessage *ldap_entry,
- char *distinguished_name);
+ char *distinguished_name);
int moira_disconnect(void);
int moira_connect(void);
void print_to_screen(const char *fmt, ...);
-int retrieve_attributes(LDAP *ldap_handle, LDAPMessage *ldap_entry,
- char *distinguished_name, LK_ENTRY **linklist_current);
-int retrieve_entries(LDAP *ldap_handle, LDAPMessage *ldap_entry,
- LK_ENTRY **linklist_base, int *linklist_count);
-int retrieve_values(LDAP *ldap_handle, LDAPMessage *ldap_entry,
- char *Attribute, char *distinguished_name,
- LK_ENTRY **linklist_current);
int main(int argc, char **argv)
{
- unsigned long rc;
- int beforec, afterc, Max_wait_time = 500, Max_size_limit = LDAP_NO_LIMIT;
- char ldap_hostname[256], search_exp[1024];
- char *dn_path, *table, **before, **after;
- ULONG version = LDAP_VERSION3;
- LDAP *ldap_handle;
- LDAPMessage *ldap_entry;
+ unsigned long rc;
+ int beforec;
+ int afterc;
+ int Max_wait_time = 500;
+ int Max_size_limit = LDAP_NO_LIMIT;
+ int i;
+ char *dn_path;
+ char *table;
+ char **before;
+ char **after;
+ char search_exp[1024];
+ char *server_name[MAX_SERVER_NAMES];
+ ULONG version = LDAP_VERSION3;
+ LDAP *ldap_handle;
+ LDAPMessage *ldap_entry;
FILE *fptr;
-
+
whoami = ((whoami = (char *)strrchr(argv[0], '/')) ? whoami+1 : argv[0]);
- /*
- * if (argc < 4)
- * exit(1);
- *
- * beforec = atoi(argv[2]);
- * afterc = atoi(argv[3]);
- *
- * if (argc < (4 + beforec + afterc))
- * exit(1);
- *
- * table = argv[1];
- * before = &argv[4];
- * after = &argv[4 + beforec];
- */
- memset(ldap_hostname, '\0', sizeof(ldap_hostname));
+
+ if (argc < 4)
+ {
+ com_err(whoami, 0, "%s", "argc < 4");
+ exit(1);
+ }
+ beforec = atoi(argv[2]);
+ afterc = atoi(argv[3]);
+
+ if (argc < (4 + beforec + afterc))
+ {
+ com_err(whoami, 0, "%s", "argc < (4 + breforec + afterc)");
+ exit(1);
+ }
+
+ table = argv[1];
+ before = &argv[4];
+ after = &argv[4 + beforec];
+
+ memset(ldap_domain, '\0', sizeof(ldap_domain));
if ((fptr = fopen("winad.cfg", "r")) != NULL)
{
- fread(ldap_hostname, sizeof(char), sizeof(ldap_hostname), fptr);
+ fread(ldap_domain, sizeof(char), sizeof(ldap_domain), fptr);
fclose(fptr);
}
- if (strlen(ldap_hostname) == 0)
- strcpy(ldap_hostname, "windows.mit.edu");
-
+ if (strlen(ldap_domain) == 0)
+ strcpy(ldap_domain, "windows.mit.edu");
initialize_sms_error_table();
initialize_krb_error_table();
-
+
memset(search_exp, '\0', sizeof(search_exp));
ldap_entry = NULL;
dn_path = NULL;
- convert_domain_to_dn(ldap_hostname, &dn_path);
+ convert_domain_to_dn(ldap_domain, &dn_path);
if (dn_path == NULL)
- exit(1);
-
- ldap_handle = ldap_open(ldap_hostname, LDAP_PORT);
- if (ldap_handle == NULL)
- exit(1);
+ {
+ com_err(whoami, 0, "%s", "cannot create AD path");
+ exit(1);
+ }
+ memset(server_name, '\0', sizeof(server_name[0]) * MAX_SERVER_NAMES);
+ if (locate_ldap_server(ldap_domain, server_name) == -1)
+ {
+ com_err(whoami, 0, "%s %s", "cannot locate any server in domain ",
+ ldap_domain);
+ exit(1);
+ }
+
+ for (i = 0; i < MAX_SERVER_NAMES; i++)
+ {
+ if (server_name[i] != NULL)
+ {
+ if ((ldap_handle = ldap_open(server_name[i], LDAP_PORT)) != NULL)
+ {
+ break;
+ }
+ }
+ }
+ if (i >= MAX_SERVER_NAMES)
+ {
+ com_err(whoami, 0, "%s %s", "cannot connect to any server in domain ",
+ ldap_domain);
+ exit(1);
+ }
+ for (i = 0; i < MAX_SERVER_NAMES; i++)
+ {
+ if (server_name[i] != NULL)
+ free(server_name[i]);
+ }
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_NO_SECURITY_LAYER);
+ rc = ldap_adgssapi_bind(ldap_handle, dn_path, GSSSASL_PRIVACY_PROTECTION);
if (rc != LDAP_SUCCESS)
- exit(1);
-
- /* used for testing
- * do_list(ldap_handle, dn_path, ldap_hostname, before, beforec, after,
- * afterc);
- */
-
- rc = group_update(ldap_handle, ldap_hostname, "testaccountF", NULL,
- GROUP_CREATE, NULL);
- printf("first rc = %d\n", rc);
- if (rc != 0)
- exit(1);
- rc = group_update(ldap_handle, ldap_hostname, "pismere-team",
- "testaccountF", GROUP_MOVE_MEMBERS, NULL);
- printf("second rc = %d\n", rc);
- if (rc != 0)
- exit(1);
- rc = group_update(ldap_handle, ldap_hostname, "testaccountF", NULL,
- GROUP_DELETE, NULL);
- printf("third rc = %d\n", rc);
- exit(1);
-
+ exit(1);
+
if (!strcmp(table, "users"))
- {
- sprintf(search_exp, "(sAMAccountName=%s)", before[U_NAME]);
- if ((rc = ldap_search_s(ldap_handle, dn_path, LDAP_SCOPE_SUBTREE,
- search_exp, NULL, 0, &ldap_entry))
- == LDAP_SUCCESS)
- do_user(ldap_handle, ldap_entry, ldap_hostname, dn_path, before,
- beforec, after, afterc);
- rc = ldap_msgfree(ldap_entry);
- }
+ do_user(ldap_handle, ldap_entry, ldap_domain, dn_path, before, beforec,
+ after, afterc);
else if (!strcmp(table, "list"))
- do_list(ldap_handle, dn_path, ldap_hostname, before, beforec, after,
- afterc);
+ do_list(ldap_handle, dn_path, ldap_domain, before, beforec, after,
+ afterc);
else if (!strcmp(table, "imembers"))
- do_member(ldap_handle, dn_path, ldap_hostname, before, beforec, after,
- afterc);
- /*
- * else if (!strcmp(table, "filesys"))
- * do_filesys(before, beforec, after, afterc);
- * else if (!strcmp(table, "quota"))
- * do_quota(before, beforec, after, afterc);
- */
+ do_member(ldap_handle, dn_path, ldap_domain, before, beforec, after,
+ afterc);
+/*
+ else if (!strcmp(table, "filesys"))
+ do_filesys(before, beforec, after, afterc);
+ else if (!strcmp(table, "quota"))
+ do_quota(before, beforec, after, afterc);
+*/
rc = ldap_unbind_s(ldap_handle);
free(dn_path);
-
exit(0);
}
-void do_list(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
- char **before, int beforec, char **after, int afterc)
+void do_list(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
+ char **before, int beforec, char **after, int afterc)
{
- int agid = 0, bgid = 0, ahide, bhide;
- long rc, id;
- char *av[2];
-
+ int agid;
+ int bgid;
+ int ahide;
+ int bhide;
+ long rc;
+ char *av[3];
+ char *call_args[6];
+
+ agid = bgid = 0;
if (beforec > L_GID && atoi(before[L_ACTIVE]) && atoi(before[L_GROUP]))
{
bgid = atoi(before[L_GID]);
agid = atoi(after[L_GID]);
ahide = atoi(after[L_HIDDEN]);
}
-
+
if (agid == 0 && bgid == 0)
return;
-
+
+ if (rc = moira_connect())
+ {
+ critical_alert("AD incremental",
+ "Error contacting Moira server: %s",
+ error_message(rc));
+ return;
+ }
+
if (agid && bgid)
{
if (strcmp(after[L_NAME], before[L_NAME]))
- {
- com_err(whoami, 0, "Changing group %s to %s",
- before[L_NAME], after[L_NAME]);
-
- if (!(rc = group_update(ldap_handle, ldap_hostname,
- after[L_NAME], NULL, GROUP_CREATE, NULL)))
- {
- if (!(rc = group_update(ldap_handle, ldap_hostname,
- before[L_NAME], after[L_NAME],
- GROUP_MOVE_MEMBERS, NULL)))
- {
- rc = group_update(ldap_handle, ldap_hostname,
- before[L_NAME], NULL, GROUP_DELETE,
- NULL);
- }
- }
- if (rc)
- {
- critical_alert("incremental", "Couldn't change group %s "
- "to %s", before[L_NAME], after[L_NAME]);
- }
- }
- return;
+ {
+ com_err(whoami, 0, "Changing group %s to %s",
+ before[L_NAME], after[L_NAME]);
+
+ av[0] = after[L_NAME];
+ call_args[0] = (char *)ldap_handle;
+ call_args[1] = dn_path;
+ call_args[2] = after[L_NAME];
+ call_args[3] = NULL;
+ call_args[4] = NULL;
+ member_base = NULL;
+ sid_base = NULL;
+ sid_ptr = &sid_base;
+ if (rc = mr_query("get_list_info", 1, av, group_create, call_args))
+ {
+ critical_alert("AD incremental", "Couldn't find group %s ",
+ after[L_NAME]);
+ }
+ else
+ {
+ if (sid_base != NULL)
+ {
+ sid_update(ldap_handle, dn_path);
+ linklist_free(sid_base);
+ }
+ if (!(rc = mr_query("get_members_of_list", 1, av,
+ member_list_build, call_args)))
+ {
+ rc = member_list_process(ldap_handle, dn_path,
+ after[L_NAME], call_args[3],
+ call_args[4]);
+ }
+ if (rc = group_ad_delete(ldap_handle, dn_path, before[L_NAME]))
+ {
+ av[0] = before[L_NAME];
+ if (rc = mr_query("get_list_info", 1, av, group_delete,
+ call_args))
+ {
+ critical_alert("AD incremental", "Couldn't delete group %s ",
+ before[L_NAME]);
+ }
+ }
+ }
+ linklist_free(member_base);
+ if (call_args[3] != NULL)
+ free(call_args[3]);
+ if (call_args[4] != NULL)
+ free(call_args[4]);
+ }
+ goto cleanup;
}
if (bgid)
{
com_err(whoami, 0, "Deleting group %s", before[L_NAME]);
- rc = group_update(ldap_handle, ldap_hostname, before[L_NAME], NULL,
- GROUP_DELETE, NULL);
- if (rc)
- {
- critical_alert("incremental",
- "Couldn't delete group %s (id %d)",
- before[L_NAME], -bgid);
- }
- return;
+ if (rc = group_ad_delete(ldap_handle, dn_path, before[L_NAME]))
+ {
+ av[0] = before[L_NAME];
+ call_args[0] = (char *)ldap_handle;
+ call_args[1] = dn_path;
+ if (!(rc = mr_query("get_list_info", 1, av, group_delete,
+ call_args)))
+ {
+ critical_alert("AD incremental",
+ "Couldn't delete group %s",
+ before[L_NAME]);
+ }
+ }
+ goto cleanup;
}
if (agid)
{
- id = -agid;
com_err(whoami, 0, "Creating group %s", after[L_NAME]);
- rc = group_update(ldap_handle, ldap_hostname, after[L_NAME], NULL,
- GROUP_CREATE, NULL);
- if (rc)
- {
- critical_alert("incremental", "Couldn't create group %s (id %d)",
- after[L_NAME], id);
- return;
- }
-
- if (beforec < L_ACTIVE)
- return;
-
- rc = moira_connect();
- if (rc)
- {
- critical_alert("incremental",
- "Error contacting Moira server to resolve %s: %s",
- after[L_NAME], error_message(rc));
- return;
- }
+
av[0] = after[L_NAME];
- rc = mr_query("get_end_members_of_list", 1, av,
- add_list_members, after[L_NAME]);
+ call_args[0] = (char *)ldap_handle;
+ call_args[1] = dn_path;
+ call_args[2] = after[L_NAME];
+ call_args[3] = NULL;
+ call_args[4] = NULL;
+ sid_base = NULL;
+ sid_ptr = &sid_base;
+ rc = mr_query("get_list_info", 1, av, group_create, call_args);
+ if ((rc) && (rc != LDAP_ALREADY_EXISTS))
+ {
+ critical_alert("AD incremental", "Couldn't create group %s",
+ after[L_NAME]);
+ goto cleanup;
+ }
+ if (sid_base != NULL)
+ {
+ sid_update(ldap_handle, dn_path);
+ linklist_free(sid_base);
+ }
+
+ if (beforec < L_ACTIVE)
+ goto cleanup;
+ if (!(rc = mr_query("get_members_of_list", 1, av, member_list_build,
+ call_args)))
+ {
+ rc = member_list_process(ldap_handle, dn_path, after[L_NAME],
+ call_args[3], call_args[4]);
+ }
if (rc)
- {
- critical_alert("incremental",
- "Couldn't retrieve full membership of list %s: %s",
- after[L_NAME], error_message(rc));
- }
- rc = group_update(ldap_handle, ldap_hostname, after[L_NAME], NULL,
- GROUP_UPDATE_MEMBERS, member_base);
+ {
+ critical_alert("AD incremental",
+ "Error contacting Moira server to resolve %s: %s",
+ after[L_NAME], error_message(rc));
+ }
linklist_free(member_base);
- moira_disconnect();
- return;
+ goto cleanup;
}
+cleanup:
+ moira_disconnect();
}
#define LM_EXTRA_ACTIVE (LM_END)
#define LM_EXTRA_END (LM_END+6)
void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
- char **before, int beforec, char **after, int afterc)
+ char **before, int beforec, char **after, int afterc)
{
+ char *call_args[6];
+ char *av[2];
+ char group_name[128];
+ char user_name[128];
+ int rc;
+
if (afterc)
{
if (afterc < LM_EXTRA_END)
- return;
+ return;
else
- {
- if (!atoi(after[LM_EXTRA_ACTIVE]) || !atoi(after[LM_EXTRA_GROUP]))
- return;
- }
- edit_group(1, after[LM_LIST], after[LM_TYPE], after[LM_MEMBER],
- ldap_handle, dn_path, ldap_hostname);
+ {
+ if (!atoi(after[LM_EXTRA_ACTIVE]) || !atoi(after[LM_EXTRA_GROUP]))
+ return;
+ }
+ strcpy(user_name, after[U_NAME]);
+ strcpy(group_name, after[LM_LIST]);
}
else if (beforec)
{
if (beforec < LM_EXTRA_END)
- return;
+ return;
else
- {
- if (!atoi(before[LM_EXTRA_ACTIVE]) || !atoi(before[LM_EXTRA_GROUP]))
- return;
- }
- edit_group(0, before[LM_LIST], before[LM_TYPE], before[LM_MEMBER],
- ldap_handle, dn_path, ldap_hostname);
+ {
+ if (!atoi(before[LM_EXTRA_ACTIVE]) || !atoi(before[LM_EXTRA_GROUP]))
+ return;
+ }
+ strcpy(user_name, before[U_NAME]);
+ strcpy(group_name, before[LM_LIST]);
}
+
+
+ if (rc = moira_connect())
+ {
+ critical_alert("AD incremental",
+ "Moira error retrieving grouplist of user %s: %s",
+ user_name, error_message(rc));
+ return;
+ }
+ av[0] = group_name;
+ call_args[0] = (char *)ldap_handle;
+ call_args[1] = dn_path;
+ call_args[2] = group_name;
+ call_args[3] = NULL;
+ call_args[4] = NULL;
+ member_base = NULL;
+ sid_base = NULL;
+ sid_ptr = &sid_base;
+ if (!(rc = mr_query("get_list_info", 1, av, group_create, call_args)))
+ {
+ if (sid_base != NULL)
+ {
+ sid_update(ldap_handle, dn_path);
+ linklist_free(sid_base);
+ }
+ if (!(rc = mr_query("get_members_of_list", 1, av, member_list_build,
+ call_args)))
+ {
+ rc = member_list_process(ldap_handle, dn_path, group_name,
+ call_args[3], call_args[4]);
+ }
+ else
+ {
+ if (rc == MR_NO_MATCH)
+ {
+ if (call_args[3] != NULL)
+ free(call_args[3]);
+ if (call_args[4] != NULL)
+ free(call_args[4]);
+ call_args[3] = NULL;
+ call_args[4] = NULL;
+ sid_base = NULL;
+ sid_ptr = &sid_base;
+ rc = group_ad_delete(ldap_handle, dn_path, group_name);
+ if (!(rc = mr_query("get_list_info", 1, av, group_create, call_args)))
+ {
+ if (sid_base != NULL)
+ {
+ sid_update(ldap_handle, dn_path);
+ linklist_free(sid_base);
+ }
+ }
+ }
+ }
+ }
+ if (rc)
+ {
+ if (afterc)
+ critical_alert("AD incremental", "Couldn't add %s to group %s ",
+ user_name, group_name);
+ else
+ critical_alert("AD incremental", "Couldn't remove %s from group %s ",
+ user_name, group_name);
+ }
+ linklist_free(member_base);
+ if (call_args[3] != NULL)
+ free(call_args[3]);
+ if (call_args[4] != NULL)
+ free(call_args[4]);
+ moira_disconnect();
}
+
void do_user(LDAP *ldap_handle, LDAPMessage *ldap_entry, char *ldap_hostname,
- char *dn_path, char **before, int beforec, char **after,
- int afterc)
+ char *dn_path, char **before, int beforec, char **after,
+ int afterc)
{
- int astate = 0, bstate = 0, auid = 0, buid = 0, rc;
- char *av[2];
-
+ int astate;
+ int bstate;
+ int auid;
+ int buid;
+ int rc;
+ char *av[2];
+ LK_ENTRY *list_base;
+ LK_ENTRY *ptr;
+ char *call_args[6];
+
+ auid = buid = astate = bstate = 0;
if (afterc > U_STATE)
astate = atoi(after[U_STATE]);
if (beforec > U_STATE)
auid = atoi(after[U_UID]);
if (beforec > U_UID)
buid = atoi(before[U_UID]);
-
+
if (astate == 2)
astate = 1;
if (bstate == 2)
bstate = 1;
-
+
if (astate != 1 && bstate != 1) /* inactive user */
return;
-
- if ((astate == bstate) && (auid == buid) &&
- !strcmp(before[U_NAME], after[U_NAME]))
+
+ if (astate == bstate && auid == buid && !strcmp(before[U_NAME], after[U_NAME]))
return;
-
- if (astate == bstate)
- {
- com_err(whoami, 0, "Changing user %s to %s", before[U_NAME],
- after[U_NAME]);
- rc = member_update(ldap_handle, dn_path, ldap_entry, before[U_NAME],
- after[U_NAME], ldap_hostname, MEMBER_CHANGE_NAME,
- NULL);
- if (rc)
- {
- critical_alert("incremental",
- "Couldn't change user %s (id %d) to %s (id %d)",
- before[U_NAME], buid, after[U_NAME], auid);
- }
- return;
- }
- if (bstate == 1)
+ if (rc = moira_connect())
{
- com_err(whoami, 0, "Deleting user %s", before[U_NAME]);
- rc = member_update(ldap_handle, dn_path, ldap_entry, before[U_NAME],
- NULL, ldap_hostname, MEMBER_DEACTIVATE, NULL);
- if (rc)
- {
- critical_alert("incremental", "Couldn't deactivate user %s (id %d)",
- before[U_NAME], buid);
- }
- return;
- }
- if (astate == 1)
- {
- com_err(whoami, 0, "%s user %s",
- ((bstate != 0) ? "Reactivating" : "Creating"),
- after[U_NAME]);
-
- rc = member_update(ldap_handle, dn_path, ldap_entry, after[U_NAME],
- NULL, ldap_hostname, MEMBER_ACTIVATE, NULL);
- if (rc)
- {
- critical_alert("incremental", "Couldn't activate user %s (id %d)",
- after[U_NAME], auid);
- return;
- }
- if (bstate != 0)
- {
- /* Reactivating a user; get his group list */
- rc = moira_connect();
- if (rc)
- {
- critical_alert("incremental", "Error contacting Moira server "
- "to retrieve grouplist of user %s: %s",
- after[U_NAME], error_message(rc));
- return;
- }
- av[0] = "ruser";
- av[1] = after[U_NAME];
- member_base = NULL;
- rc = mr_query("get_lists_of_member", 2, av, add_user_lists,
- after[U_NAME]);
- if (rc && rc != MR_NO_MATCH)
- {
- critical_alert("incremental",
- "Couldn't retrieve membership of user %s: %s",
- after[U_NAME], error_message(rc));
- }
- else
- {
- rc = member_update(ldap_handle, dn_path, ldap_entry,
- after[U_NAME], NULL, ldap_hostname,
- MEMBER_ADD, member_base);
- linklist_free(member_base);
- }
- moira_disconnect();
- }
+ critical_alert("AD incremental",
+ "Error connection to Moira: %s",
+ error_message(rc));
return;
}
-}
-int group_update(LDAP *ldap_handle, char *ldap_hostname, char *group_name,
- char *after_group_name, int operation, LK_ENTRY *user_list)
-{
- char distinguished_name[1024], filter_exp[1024], temp[256];
- char ***modvalues, *attr_array[3], *dn_path = NULL;
- int newvalue_count, group_count, sPtr_count;
- LDAPMod **newvalue_array;
- LK_ENTRY *group_base;
- LK_ENTRY **sPtr;
- LK_ENTRY *pPtr;
- ULONG rc = 0;
-
- convert_domain_to_dn(ldap_hostname, &dn_path);
-
- newvalue_array = NULL;
- newvalue_count = 0;
- modvalues = NULL;
- group_base = NULL;
- group_count = 0;
- newvalue_count = 0;
- newvalue_array = NULL;
- modvalues = NULL;
- if ((newvalue_array = calloc(1, (5+1) * sizeof(LDAPMod *))) == NULL)
+ if (astate == bstate)
{
- rc = 1;
+ com_err(whoami, 0, "Changing user %s to %s", before[U_NAME],
+ after[U_NAME]);
+ av[0] = after[U_NAME];
+ call_args[0] = (char *)ldap_handle;
+ call_args[1] = dn_path;
+ sid_base = NULL;
+ sid_ptr = &sid_base;
+ if (rc = mr_query("get_user_account_by_login", 1, av, user_create,
+ call_args))
+ {
+ critical_alert("AD incremental",
+ "Couldn't change user name for %s to %s",
+ before[U_NAME], after[U_NAME]);
+ goto cleanup;
+ }
+ if (sid_base != NULL)
+ {
+ sid_update(ldap_handle, dn_path);
+ linklist_free(sid_base);
+ }
+ user_delete(ldap_handle, dn_path, before[U_NAME]);
+ av[0] = "ruser";
+ av[1] = after[U_NAME];
+ call_args[0] = after[U_NAME];
+ member_base = NULL;
+ if (rc = mr_query("get_lists_of_member", 2, av, group_list_build,
+ call_args))
+ {
+ critical_alert("AD incremental",
+ "Couldn't retrieve membership of user %s: %s",
+ after[U_NAME], error_message(rc));
+ goto cleanup;
+ }
+ list_base = member_base;
+ ptr = list_base;
+ while (ptr)
+ {
+ rc = group_update_membership(ldap_handle, dn_path, ptr->list);
+ ptr = ptr->next;
+ }
+ linklist_free(list_base);
goto cleanup;
}
- newvalue_array[0] = NULL;
- newvalue_array[1] = NULL;
- newvalue_array[2] = NULL;
- newvalue_array[3] = NULL;
- newvalue_array[4] = NULL;
- if ((modvalues = calloc(1, (5+1) * sizeof(char **))) == NULL)
+ if (bstate == 1)
{
- rc = 1;
+ com_err(whoami, 0, "Deactivate/Delete user %s from the AD", before[U_NAME]);
+ if (rc = user_delete(ldap_handle, dn_path, before[U_NAME]))
+ {
+ critical_alert("AD incremental",
+ "Couldn't deactivate/delete user %s (id %d) from the AD",
+ before[U_NAME], buid);
+ }
goto cleanup;
}
- modvalues[0] = NULL;
- modvalues[1] = NULL;
- modvalues[2] = NULL;
- modvalues[3] = NULL;
- modvalues[4] = NULL;
-
- if (operation == GROUP_DELETE)
- {
- sprintf(filter_exp, "(sAMAccountName=%s)", group_name);
- attr_array[0] = "distinguishedName";
- attr_array[1] = NULL;
- if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array,
- &group_base, &group_count)) != 0)
- goto cleanup;
- if (group_count == 1)
- rc = ldap_delete_s(ldap_handle, group_base->value);
- if (rc != LDAP_SUCCESS)
- {
- critical_alert("incremental",
- "Couldn't delete group %s: %s",
- group_name, ldap_err2string(rc));
- goto cleanup;
- }
- }
- else if (operation == GROUP_CREATE)
- {
- linklist_create_entry("cn", group_name, &group_base);
- group_count = 1;
- if ((rc = construct_newvalues(group_base, group_count, newvalue_count,
- NULL, NULL, &newvalue_array, &modvalues,
- REPLACE)) == 1)
- goto cleanup;
- newvalue_array[newvalue_count]->mod_op = LDAP_MOD_ADD;
- newvalue_array[newvalue_count]->mod_type = "cn";
- newvalue_array[newvalue_count]->mod_values = modvalues[newvalue_count];
- linklist_free(group_base);
- group_base = NULL;
-
- ++newvalue_count;
- linklist_create_entry("name", group_name, &group_base);
- group_count = 1;
- if ((rc = construct_newvalues(group_base, group_count, newvalue_count,
- NULL, NULL, &newvalue_array, &modvalues,
- REPLACE)) == 1)
- goto cleanup;
- newvalue_array[newvalue_count]->mod_op = LDAP_MOD_ADD;
- newvalue_array[newvalue_count]->mod_type = "name";
- newvalue_array[newvalue_count]->mod_values = modvalues[newvalue_count];
- linklist_free(group_base);
- group_base = NULL;
-
- ++newvalue_count;
- linklist_create_entry("objectClass","top", &group_base);
- linklist_create_entry("objectClass", "group", &group_base->next);
- group_count = 2;
- if ((rc = construct_newvalues(group_base, group_count, newvalue_count,
- NULL, NULL, &newvalue_array, &modvalues,
- REPLACE)) == 1)
- goto cleanup;
- newvalue_array[newvalue_count]->mod_op = LDAP_MOD_ADD;
- newvalue_array[newvalue_count]->mod_type = "objectClass";
- newvalue_array[newvalue_count]->mod_values = modvalues[newvalue_count];
- linklist_free(group_base);
- group_base = NULL;
-
- ++newvalue_count;
- linklist_create_entry("sAMAccountName", group_name, &group_base);
- group_count = 1;
- if ((rc = construct_newvalues(group_base, group_count, newvalue_count,
- NULL, NULL, &newvalue_array, &modvalues,
- REPLACE)) == 1)
- goto cleanup;
- newvalue_array[newvalue_count]->mod_op = LDAP_MOD_ADD;
- newvalue_array[newvalue_count]->mod_type = "sAMAccountName";
- newvalue_array[newvalue_count]->mod_values = modvalues[newvalue_count];
- linklist_free(group_base);
- group_base = NULL;
-
- sprintf(temp,"CN=%s,%s,%s", group_name, group_ou, dn_path);
- rc = ldap_add_s(ldap_handle, temp, newvalue_array);
- if (rc != LDAP_SUCCESS)
- {
- critical_alert("incremental",
- "Couldn't create group %s: %s",
- group_name, ldap_err2string(rc));
- goto cleanup;
- }
- }
- else if (operation == GROUP_UPDATE_MEMBERS)
- {
- sprintf(filter_exp, "(sAMAccountName=%s)", group_name);
- attr_array[0] = "distinguishedName";
- attr_array[1] = NULL;
- if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array,
- &group_base, &group_count)) != 0)
- goto cleanup;
- if (group_count != 1)
- {
- rc = 1;
- goto cleanup;
- }
- strcpy(distinguished_name, group_base->value);
- linklist_free(group_base);
-
- pPtr = member_base;
- group_base = NULL;
- group_count = 0;
- sPtr = &group_base;
- while (pPtr)
- {
- sprintf(filter_exp, "(sAMAccountName=%s)", pPtr->member);
- attr_array[0] = "distinguishedName";
- attr_array[1] = NULL;
- if ((*sPtr) != NULL)
- sPtr = &((*sPtr)->next);
- sPtr_count = 0;
- if ((rc = linklist_build(ldap_handle, dn_path, filter_exp,
- attr_array, sPtr, &sPtr_count)) != 0)
- goto cleanup;
- if (sPtr_count != 0)
- group_count += sPtr_count;
- pPtr = pPtr->next;
- }
- if (group_count != 0)
- {
- if ((rc = construct_newvalues(group_base, group_count,
- newvalue_count, NULL, NULL,
- &newvalue_array, &modvalues,
- REPLACE)) == 1)
- goto cleanup;
- linklist_free(group_base);
- newvalue_array[newvalue_count]->mod_type = "member";
- newvalue_array[newvalue_count]->mod_values =
- modvalues[newvalue_count];
- newvalue_array[newvalue_count]->mod_op = LDAP_MOD_ADD;
- rc = ldap_modify_s(ldap_handle, distinguished_name, newvalue_array);
- group_count = 0;
- group_base = NULL;
- if (rc != LDAP_SUCCESS)
- {
- critical_alert("incremental",
- "Couldn't add users to group %s: %s",
- group_name, ldap_err2string(rc));
- goto cleanup;
- }
- }
- }
- else if (operation == GROUP_MOVE_MEMBERS)
+ if (astate == 1)
{
- sprintf(filter_exp, "(sAMAccountName=%s)", after_group_name);
- attr_array[0] = "distinguishedName";
- attr_array[1] = NULL;
- if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array,
- &group_base, &group_count)) != 0)
- goto cleanup;
- if (group_count != 1)
- {
- rc = 1;
- goto cleanup;
- }
- strcpy(distinguished_name, group_base->value);
- linklist_free(group_base);
-
- group_base = NULL;
- group_count = 0;
- sprintf(filter_exp, "(sAMAccountName=%s)", group_name);
- attr_array[0] = "member";
- attr_array[1] = NULL;
- if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array,
- &group_base, &group_count)) != 0)
- goto cleanup;
-
- if (group_count != 0)
- {
- if ((rc = construct_newvalues(group_base, group_count,
- newvalue_count, NULL, NULL,
- &newvalue_array, &modvalues,
- REPLACE)) == 1)
- goto cleanup;
- linklist_free(group_base);
- newvalue_array[newvalue_count]->mod_type = "member";
- newvalue_array[newvalue_count]->mod_values =
- modvalues[newvalue_count];
- newvalue_array[newvalue_count]->mod_op = LDAP_MOD_ADD;
- rc = ldap_modify_s(ldap_handle, distinguished_name, newvalue_array);
- group_count = 0;
- group_base = NULL;
- if (rc != LDAP_SUCCESS)
- {
- critical_alert("incremental",
- "Couldn't add users to group %s: %s",
- group_name, ldap_err2string(rc));
- goto cleanup;
- }
- }
- }
-
- cleanup:
- free_values(newvalue_count, newvalue_array, modvalues);
- linklist_free(group_base);
- if (dn_path != NULL)
- free(dn_path);
- if (rc == 1)
- critical_alert("incremental",
- "Couldn't process group %s: %s",
- group_name, "Cannot calloc - out of memory");
- return(rc);
-}
+ com_err(whoami, 0, "%s user %s",
+ ((bstate != 0) ? "Reactivating" : "Creating"),
+ after[U_NAME]);
-int member_update(LDAP *ldap_handle, char *cn_path, LDAPMessage *ldap_entry,
- char *login_name, char *new_login_name, char *ldap_hostname,
- int operation, LK_ENTRY *group_list)
-{
- char distinguished_name[1024], filter_exp[1024], temp[64];
- char ***modvalues; /* each *mod has a char **modvalue */
- char *attr_array[3], *dn_path = NULL;
- int newvalue_count, memberOf_count, group_count, processGroup_count;
- LDAPMod **newvalue_array;
- LK_ENTRY *processGroup;
- LK_ENTRY *processGroup_base;
- LK_ENTRY *memberOf_base;
- LK_ENTRY *group_base;
- LK_ENTRY *gPtr;
- LK_ENTRY *sPtr;
- LK_ENTRY *pPtr;
- ULONG rc;
- ULONG ulongValue;
-
- memset(distinguished_name, '\0', sizeof(distinguished_name));
- get_distinguished_name(ldap_handle, ldap_entry, distinguished_name);
- if (strlen(distinguished_name) == 0)
- return(1);
-
- convert_domain_to_dn(ldap_hostname, &dn_path);
-
- memberOf_base = NULL;
- processGroup_base = NULL;
- processGroup = NULL;
- newvalue_array = NULL;
- newvalue_count = 0;
- modvalues = NULL;
- group_count = 0;
- group_base = NULL;
-
- if ((newvalue_array = calloc(1, (3+1) * sizeof(LDAPMod *))) == NULL)
- {
- rc = 1;
- goto cleanup;
- }
- newvalue_array[0] = NULL;
- newvalue_array[1] = NULL;
- newvalue_array[2] = NULL;
- newvalue_array[3] = NULL;
- if ((modvalues = calloc(1, (3+1) * sizeof(char **))) == NULL)
- {
- rc = 1;
- goto cleanup;
- }
- modvalues[0] = NULL;
- modvalues[1] = NULL;
- modvalues[2] = NULL;
- modvalues[3] = NULL;
-
- if (operation == MEMBER_CHANGE_NAME)
- {
- sprintf(filter_exp, "(sAMAccountName=%s)", login_name);
- attr_array[0] = "sAMAccountName";
- attr_array[1] = NULL;
- if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array,
- &group_base, &group_count)) != 0)
- goto cleanup;
-
- if (group_count != 0)
- {
- if ((rc = construct_newvalues(group_base, group_count,
- newvalue_count, login_name,
- new_login_name, &newvalue_array,
- &modvalues, REPLACE)) == 1)
- goto cleanup;
- newvalue_array[newvalue_count]->mod_op = LDAP_MOD_REPLACE ;
- newvalue_array[newvalue_count]->mod_type = "sAMAccountName";
- newvalue_array[newvalue_count]->mod_values =
- modvalues[newvalue_count];
- linklist_free(group_base);
- group_count = 0;
- group_base = NULL;
- ++newvalue_count;
- }
-
- sprintf(filter_exp, "(sAMAccountName=%s)", login_name);
- attr_array[0] = "UserPrincipalName";
- attr_array[1] = NULL;
- if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array,
- &group_base, &group_count)) != 0)
- goto cleanup;
- if (group_count != 0)
- {
- if ((rc = construct_newvalues(group_base, group_count,
- newvalue_count, login_name,
- new_login_name, &newvalue_array,
- &modvalues, SUBSTITUTE)) == 1)
- goto cleanup;
- newvalue_array[newvalue_count]->mod_op = LDAP_MOD_REPLACE ;
- newvalue_array[newvalue_count]->mod_type = "UserPrincipalName";
- newvalue_array[newvalue_count]->mod_values =
- modvalues[newvalue_count];
- linklist_free(group_base);
- group_count = 0;
- group_base = NULL;
- ++newvalue_count;
- }
-
- sprintf(filter_exp, "(sAMAccountName=%s)", login_name);
- attr_array[0] = "AltSecurityIdentities";
- attr_array[1] = NULL;
- if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array,
- &group_base, &group_count)) != 0)
- goto cleanup;
- if (group_count != 0)
- {
- if ((rc = construct_newvalues(group_base, group_count,
- newvalue_count, login_name,
- new_login_name, &newvalue_array,
- &modvalues, SUBSTITUTE)) == 1)
- goto cleanup;
- newvalue_array[newvalue_count]->mod_op = LDAP_MOD_REPLACE ;
- newvalue_array[newvalue_count]->mod_type = "AltSecurityIdentities";
- newvalue_array[newvalue_count]->mod_values =
- modvalues[newvalue_count];
- linklist_free(group_base);
- group_count = 0;
- group_base = NULL;
- ++newvalue_count;
- }
-
- if (newvalue_count != 0)
- rc = ldap_modify_s(ldap_handle, distinguished_name, newvalue_array);
- if (rc != LDAP_SUCCESS)
- {
- critical_alert("incremental",
- "Couldn't process user %s: %s",
- login_name, ldap_err2string(rc));
- }
- goto cleanup;
- }
- if ((operation == MEMBER_ACTIVATE) ||
- (operation == MEMBER_DEACTIVATE))
- {
- sprintf(filter_exp, "(sAMAccountName=%s)", login_name);
- attr_array[0] = "UserAccountControl";
- attr_array[1] = NULL;
- if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array,
- &group_base, &group_count)) != 0)
- goto cleanup;
-
- if (group_count != 0)
- {
- ulongValue = atoi((*group_base).value);
- if (operation == MEMBER_DEACTIVATE)
- ulongValue |= UF_ACCOUNTDISABLE;
- else
- ulongValue &= ~UF_ACCOUNTDISABLE;
- sprintf(temp, "%ld", ulongValue);
- if ((rc = construct_newvalues(group_base, group_count,
- newvalue_count, (*group_base).value,
- temp, &newvalue_array, &modvalues,
- REPLACE)) == 1)
- goto cleanup;
- newvalue_array[newvalue_count]->mod_op = LDAP_MOD_REPLACE ;
- newvalue_array[newvalue_count]->mod_type = "UserAccountControl";
- newvalue_array[newvalue_count]->mod_values =
- modvalues[newvalue_count];
- ++newvalue_count;
- rc = ldap_modify_s(ldap_handle, distinguished_name, newvalue_array);
- if (rc != LDAP_SUCCESS)
- {
- critical_alert("incremental",
- "Couldn't process user %s: %s",
- login_name, ldap_err2string(rc));
- }
- }
- goto cleanup;
- }
-
- sprintf(filter_exp, "(objectClass=group)");
- attr_array[0] = "cn";
- attr_array[1] = NULL;
- if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array,
- &group_base, &group_count)) != 0)
- goto cleanup;
-
- sPtr = group_list;
- while (sPtr != NULL)
- {
- gPtr = group_base;
- while (gPtr != NULL)
- {
- if (!strcmp(sPtr->list, gPtr->value))
- {
- if (sPtr->dn != NULL)
- free(sPtr->dn);
- sPtr->dn = calloc(1, strlen(gPtr->dn) + 1);
- memset(sPtr->dn, '\0', strlen(gPtr->dn) + 1);
- strcpy(sPtr->dn, gPtr->dn);
- if (sPtr->attribute != NULL)
- free(sPtr->attribute);
- sPtr->attribute = calloc(1, strlen(gPtr->attribute) + 1);
- memset(sPtr->attribute, '\0', strlen(gPtr->attribute) + 1);
- strcpy(sPtr->attribute, gPtr->attribute);
- if (sPtr->value != NULL)
- free(sPtr->value);
- sPtr->value = calloc(1, strlen(gPtr->value) + 1);
- memset(sPtr->value, '\0', strlen(gPtr->value) + 1);
- strcpy(sPtr->value, gPtr->value);
- break;
- }
- gPtr = gPtr->next;
- }
- sPtr = sPtr->next;
- }
-
- memberOf_count = 0;
- memberOf_base = NULL;
- sprintf(filter_exp, "(sAMAccountName=%s)", login_name);
- attr_array[0] = "memberOf";
- attr_array[1] = NULL;
- if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array,
- &memberOf_base, &memberOf_count)) != 0)
- goto cleanup;
-
- processGroup_count = 0;
- processGroup_base = NULL;
- sPtr = group_list;
- while (sPtr)
- {
- if (sPtr->dn == NULL)
- {
- sPtr = sPtr->next;
- continue;
- }
- gPtr = memberOf_base;
- while (gPtr)
- {
- if (!strcmp(gPtr->value, sPtr->dn))
- break;
- gPtr = gPtr->next;
- }
- if (sPtr->dn != NULL)
- {
- if (((gPtr == NULL) && (operation == MEMBER_ADD)) ||
- ((gPtr != NULL) && (operation == MEMBER_REMOVE)))
- {
- gPtr = calloc(1, sizeof(LK_ENTRY));
- memset(gPtr, '\0', sizeof(LK_ENTRY));
- gPtr->attribute = calloc(1, strlen("member") + 1);
- memset(gPtr->attribute, '\0', strlen("member") + 1);
- strcpy(gPtr->attribute, "member");
- gPtr->dn = calloc(1, strlen(sPtr->dn) + 1);
- memset(gPtr->dn, '\0', strlen(sPtr->dn) + 1);
- strcpy(gPtr->dn, sPtr->dn);
- gPtr->value = calloc(1, strlen(distinguished_name) + 1);
- memset(gPtr->value, '\0', strlen(distinguished_name) + 1);
- strcpy(gPtr->value, distinguished_name);
- if (processGroup_base != NULL)
- gPtr->next = processGroup_base;
- processGroup_base = gPtr;
- gPtr = NULL;
- ++processGroup_count;
- }
- }
- sPtr = sPtr->next;
- }
-
- linklist_free(group_base);
- linklist_free(processGroup);
- group_base = NULL;
- processGroup = NULL;
- sPtr = processGroup_base;
- while (sPtr)
- {
- newvalue_count = 0;
- newvalue_array = NULL;
- modvalues = NULL;
- processGroup = NULL;
- if ((newvalue_array = calloc(1, (1+1) * sizeof(LDAPMod *))) == NULL)
- {
- rc = 1;
- goto cleanup;
- }
- newvalue_array[0] = NULL;
- newvalue_array[1] = NULL;
- if ((modvalues = calloc(1, (1+1) * sizeof(char **))) == NULL)
- {
- rc = 1;
- goto cleanup;
- }
- modvalues[0] = NULL;
- modvalues[1] = NULL;
-
- if (operation == MEMBER_REMOVE)
- {
- processGroup_count = 0;
- processGroup = NULL;
- sprintf(filter_exp, "(distinguishedName=%s)", sPtr->dn);
- attr_array[0] = "member";
- attr_array[1] = NULL;
- if ((rc = linklist_build(ldap_handle, dn_path, filter_exp,
- attr_array, &processGroup,
- &processGroup_count)) != 0)
- goto cleanup;
- gPtr = processGroup;
- pPtr = NULL;
- while (gPtr)
- {
- if (!strcmp(gPtr->value, sPtr->value))
- {
- if (pPtr != NULL)
- pPtr->next = gPtr->next;
- else
- processGroup = gPtr->next;
- gPtr->next = NULL;
- linklist_free(gPtr);
- --processGroup_count;
- break;
- }
- pPtr = gPtr;
- gPtr = gPtr->next;
- }
- if ((rc = construct_newvalues(processGroup, processGroup_count,
- newvalue_count, NULL, NULL,
- &newvalue_array, &modvalues,
- REPLACE)) == 1)
- goto cleanup;
- newvalue_array[newvalue_count]->mod_op = LDAP_MOD_REPLACE ;
- pPtr = processGroup;
- }
- else
- {
- processGroup = calloc(1, sizeof(LK_ENTRY));
- memset(processGroup, '\0', sizeof(LK_ENTRY));
- memcpy(processGroup, sPtr, sizeof(LK_ENTRY));
- processGroup->next = NULL;
- processGroup_count = 1;
- if ((rc = construct_newvalues(processGroup, processGroup_count,
- newvalue_count, NULL, NULL,
- &newvalue_array, &modvalues,
- REPLACE)) == 1)
- goto cleanup;
- newvalue_array[newvalue_count]->mod_op = LDAP_MOD_ADD;
- pPtr = sPtr;
- }
- newvalue_array[newvalue_count]->mod_type = "member";
- newvalue_array[newvalue_count]->mod_values = modvalues[newvalue_count];
- rc = ldap_modify_s(ldap_handle, sPtr->dn, newvalue_array);
- if (operation == MEMBER_REMOVE)
- linklist_free(processGroup);
+ av[0] = after[U_NAME];
+ call_args[0] = (char *)ldap_handle;
+ call_args[1] = dn_path;
+ sid_base = NULL;
+ sid_ptr = &sid_base;
+ if (rc = mr_query("get_user_account_by_login", 1, av, user_create,
+ call_args))
+ {
+ critical_alert("AD incremental", "Couldn't activate user %s (id %d)",
+ after[U_NAME], auid);
+ goto cleanup;
+ }
+ if (sid_base != NULL)
+ {
+ sid_update(ldap_handle, dn_path);
+ linklist_free(sid_base);
+ }
+
+/*
+ av[0] = "ruser";
+ av[1] = after[U_NAME];
+ call_args[0] = after[U_NAME];
+ member_base = NULL;
+ if (rc = mr_query("get_lists_of_member", 2, av, group_list_build,
+ call_args))
+ {
+ critical_alert("AD incremental",
+ "Couldn't retrieve group membership of user %s",
+ after[U_NAME]);
+ }
else
- free(processGroup);
- processGroup = NULL;
- newvalue_count = 1;
- free_values(newvalue_count, newvalue_array, modvalues);
- newvalue_array = NULL;
- modvalues = NULL;
- if (rc != LDAP_SUCCESS)
- {
- critical_alert("incremental",
- "Couldn't process user %s: %s",
- login_name, ldap_err2string(rc));
- goto cleanup;
- }
- sPtr = sPtr->next;
- }
-
- cleanup:
- free_values(newvalue_count, newvalue_array, modvalues);
- linklist_free(memberOf_base);
- linklist_free(group_base);
- linklist_free(processGroup_base);
- free(dn_path);
- if (rc == 1)
- critical_alert("incremental",
- "Couldn't process user %s: %s",
- login_name, "Cannot calloc - out of memory");
- return(rc);
+ {
+ list_base = member_base;
+ ptr = list_base;
+ while (ptr)
+ {
+ rc = group_update_membership(ldap_handle, dn_path, ptr->list);
+ ptr = ptr->next;
+ }
+ linklist_free(list_base);
+ }
+*/
+ }
+cleanup:
+ moira_disconnect();
}
int construct_newvalues(LK_ENTRY *linklist_base, int modvalue_count,
- int newvalue_count, char *oldValue, char *newValue,
- LDAPMod ***newValueArray, char ****modvalues,
- int type)
+ char *oldValue, char *newValue,
+ char ***modvalues, int type)
{
- LK_ENTRY *linklist_ptr;
- int i;
- char *cPtr;
-
- if (((*newValueArray)[newvalue_count] =
- calloc(1, sizeof(LDAPMod))) == NULL)
- return(1);
-
- if (((*modvalues)[newvalue_count] =
- calloc(1, (modvalue_count + 1) * sizeof(char *))) == NULL)
- return(1);
+ LK_ENTRY *linklist_ptr;
+ int i;
+ char *cPtr;
+ if (((*modvalues) = calloc(1, (modvalue_count + 1) * sizeof(char *)))
+ == NULL)
+ {
+ return(1);
+ }
for (i = 0; i < (modvalue_count + 1); i++)
- (*modvalues)[newvalue_count][i] = NULL;
+ (*modvalues)[i] = NULL;
if (modvalue_count != 0)
{
linklist_ptr = linklist_base;
for (i = 0; i < modvalue_count; i++)
- {
- if ((oldValue != NULL) && (newValue != NULL))
- {
- if ((cPtr = (char *)strstr(linklist_ptr->value, oldValue))
- != (char *)NULL)
- {
- if (type == REPLACE)
- {
- if (((*modvalues)[newvalue_count][i] =
- calloc(1, strlen(newValue) + 1)) == NULL)
- return(1);
- memset((*modvalues)[newvalue_count][i], '\0',
- strlen(newValue) + 1);
- strcpy((*modvalues)[newvalue_count][i], newValue);
- }
- else
- {
- if (((*modvalues)[newvalue_count][i] =
- calloc(1, (int)(cPtr - linklist_ptr->value) +
- (linklist_ptr->length - strlen(oldValue)) +
- strlen(newValue) + 1)) == NULL)
- return(1);
- memset((*modvalues)[newvalue_count][i], '\0',
- (int)(cPtr - linklist_ptr->value) +
- (linklist_ptr->length - strlen(oldValue)) +
- strlen(newValue) + 1);
- memcpy((*modvalues)[newvalue_count][i],
- linklist_ptr->value,
- (int)(cPtr - linklist_ptr->value));
- strcat((*modvalues)[newvalue_count][i], newValue);
- strcat((*modvalues)[newvalue_count][i],
- &linklist_ptr->value[(int)(cPtr - linklist_ptr->value) + strlen(oldValue)]);
- }
- }
- else
- {
- (*modvalues)[newvalue_count][i] =
- calloc(1, linklist_ptr->length + 1);
- memset((*modvalues)[newvalue_count][i],
- '\0', linklist_ptr->length + 1);
- memcpy((*modvalues)[newvalue_count][i],
- linklist_ptr->value, linklist_ptr->length);
- }
- }
- else
- {
- (*modvalues)[newvalue_count][i] =
- calloc(1, linklist_ptr->length + 1);
- memset((*modvalues)[newvalue_count][i], '\0',
- linklist_ptr->length + 1);
- memcpy((*modvalues)[newvalue_count][i], linklist_ptr->value,
- linklist_ptr->length);
- }
- linklist_ptr = linklist_ptr->next;
- }
- (*modvalues)[newvalue_count][i] = NULL;
+ {
+ if ((oldValue != NULL) && (newValue != NULL))
+ {
+ if ((cPtr = (char *)strstr(linklist_ptr->value, oldValue))
+ != (char *)NULL)
+ {
+ if (type == REPLACE)
+ {
+ if (((*modvalues)[i] = calloc(1, strlen(newValue) + 1))
+ == NULL)
+ return(1);
+ memset((*modvalues)[i], '\0', strlen(newValue) + 1);
+ strcpy((*modvalues)[i], newValue);
+ }
+ else
+ {
+ if (((*modvalues)[i] = calloc(1,
+ (int)(cPtr - linklist_ptr->value) +
+ (linklist_ptr->length - strlen(oldValue)) +
+ strlen(newValue) + 1)) == NULL)
+ return(1);
+ memset((*modvalues)[i], '\0',
+ (int)(cPtr - linklist_ptr->value) +
+ (linklist_ptr->length - strlen(oldValue)) +
+ strlen(newValue) + 1);
+ memcpy((*modvalues)[i], linklist_ptr->value,
+ (int)(cPtr - linklist_ptr->value));
+ strcat((*modvalues)[i], newValue);
+ strcat((*modvalues)[i],
+ &linklist_ptr->value[(int)(cPtr - linklist_ptr->value) + strlen(oldValue)]);
+ }
+ }
+ else
+ {
+ (*modvalues)[i] = calloc(1, linklist_ptr->length + 1);
+ memset((*modvalues)[i], '\0', linklist_ptr->length + 1);
+ memcpy((*modvalues)[i], linklist_ptr->value,
+ linklist_ptr->length);
+ }
+ }
+ else
+ {
+ (*modvalues)[i] = calloc(1, linklist_ptr->length + 1);
+ memset((*modvalues)[i], '\0', linklist_ptr->length + 1);
+ memcpy((*modvalues)[i], linklist_ptr->value,
+ linklist_ptr->length);
+ }
+ linklist_ptr = linklist_ptr->next;
+ }
+ (*modvalues)[i] = NULL;
}
return(0);
}
+
int linklist_build(LDAP *ldap_handle, char *dn_path, char *search_exp,
- char **attr_array, LK_ENTRY **linklist_base,
- int *linklist_count)
+ char **attr_array, LK_ENTRY **linklist_base,
+ int *linklist_count)
{
- ULONG rc = 0;
+ ULONG rc;
LDAPMessage *ldap_entry;
-
+
+ rc = 0;
ldap_entry = NULL;
(*linklist_base) = NULL;
(*linklist_count) = 0;
if ((rc = ldap_search_s(ldap_handle, dn_path, LDAP_SCOPE_SUBTREE,
- search_exp, attr_array, 0, &ldap_entry))
+ search_exp, attr_array, 0, &ldap_entry))
!= LDAP_SUCCESS)
return(0);
- rc = retrieve_entries(ldap_handle, ldap_entry, linklist_base,
- linklist_count);
-
+ rc = retrieve_entries(ldap_handle, ldap_entry, linklist_base, linklist_count);
+
ldap_msgfree(ldap_entry);
return(rc);
}
+
int retrieve_entries(LDAP *ldap_handle, LDAPMessage *ldap_entry,
- LK_ENTRY **linklist_base, int *linklist_count)
+ LK_ENTRY **linklist_base, int *linklist_count)
{
- char distinguished_name[1024];
- LK_ENTRY *linklist_ptr;
- int rc;
-
- memset(distinguished_name, '\0', sizeof(distinguished_name));
- get_distinguished_name(ldap_handle, ldap_entry, distinguished_name);
-
+ char distinguished_name[1024];
+ LK_ENTRY *linklist_ptr;
+ int rc;
+
if ((ldap_entry = ldap_first_entry(ldap_handle, ldap_entry)) == NULL)
return(0);
-
- if ((rc = retrieve_attributes(ldap_handle, ldap_entry, distinguished_name,
- linklist_base)) != 0)
+
+ memset(distinguished_name, '\0', sizeof(distinguished_name));
+ get_distinguished_name(ldap_handle, ldap_entry, distinguished_name);
+
+ if ((rc = retrieve_attributes(ldap_handle, ldap_entry, distinguished_name,
+ linklist_base)) != 0)
return(rc);
-
+
while ((ldap_entry = ldap_next_entry(ldap_handle, ldap_entry)) != NULL)
{
- if ((rc = retrieve_attributes(ldap_handle, ldap_entry,
- distinguished_name, linklist_base)) != 0)
- return(rc);
+ memset(distinguished_name, '\0', sizeof(distinguished_name));
+ get_distinguished_name(ldap_handle, ldap_entry, distinguished_name);
+
+ if ((rc = retrieve_attributes(ldap_handle, ldap_entry, distinguished_name,
+ linklist_base)) != 0)
+ return(rc);
}
-
+
linklist_ptr = (*linklist_base);
(*linklist_count) = 0;
while (linklist_ptr != NULL)
}
int retrieve_attributes(LDAP *ldap_handle, LDAPMessage *ldap_entry,
- char *distinguished_name, LK_ENTRY **linklist_current)
+ char *distinguished_name, LK_ENTRY **linklist_current)
{
- char *Attribute;
- BerElement *ptr;
-
+ char *Attribute;
+ BerElement *ptr;
+
ptr = NULL;
- if ((Attribute = ldap_first_attribute(ldap_handle, ldap_entry, &ptr))
- != NULL)
+ if ((Attribute = ldap_first_attribute(ldap_handle, ldap_entry, &ptr)) != NULL)
{
- retrieve_values(ldap_handle, ldap_entry, Attribute, distinguished_name,
- linklist_current);
+ retrieve_values(ldap_handle, ldap_entry, Attribute, distinguished_name,
+ linklist_current);
ldap_memfree(Attribute);
- while ((Attribute = ldap_next_attribute(ldap_handle, ldap_entry, ptr))
- != NULL)
- {
- retrieve_values(ldap_handle, ldap_entry, Attribute,
- distinguished_name, linklist_current);
- ldap_memfree(Attribute);
- }
+ while ((Attribute = ldap_next_attribute(ldap_handle, ldap_entry,
+ ptr)) != NULL)
+ {
+ retrieve_values(ldap_handle, ldap_entry, Attribute,
+ distinguished_name, linklist_current);
+ ldap_memfree(Attribute);
+ }
}
+ ldap_ber_free(ptr, 0);
return(0);
}
-int retrieve_values(LDAP *ldap_handle, LDAPMessage *ldap_entry,
- char *Attribute, char *distinguished_name,
- LK_ENTRY **linklist_current)
+int retrieve_values(LDAP *ldap_handle, LDAPMessage *ldap_entry,
+ char *Attribute, char *distinguished_name,
+ LK_ENTRY **linklist_current)
{
- char **str_value;
- char temp[256];
- void **Ptr;
- int use_bervalue;
- LK_ENTRY *linklist_previous;
+ char **str_value;
+ char temp[256];
+ void **Ptr;
+ int use_bervalue;
+ LK_ENTRY *linklist_previous;
LDAP_BERVAL **ber_value;
- DWORD ber_length;
+ DWORD ber_length;
#ifdef LDAP_DEBUG
- SID *sid;
- GUID *guid;
- int i;
- int intValue;
- DWORD *subauth;
- SID_IDENTIFIER_AUTHORITY *sid_auth;
- unsigned char *subauth_count;
-#endif /*LDAP_DEBUG*/
+ SID *sid;
+ GUID *guid;
+ int i;
+ int intValue;
+ DWORD *subauth;
+ SID_IDENTIFIER_AUTHORITY *sid_auth;
+ unsigned char *subauth_count;
+#endif /*LDAP_BEGUG*/
use_bervalue = 0;
memset(temp, '\0', sizeof(temp));
if ((!strcmp(Attribute, "objectSid")) ||
(!strcmp(Attribute, "objectGUID")))
use_bervalue = 1;
-
+
if (use_bervalue)
{
ber_value = ldap_get_values_len(ldap_handle, ldap_entry, Attribute);
Ptr = (void **)ber_value;
str_value = NULL;
- }
+ }
else
{
str_value = ldap_get_values(ldap_handle, ldap_entry, Attribute);
if (Ptr != NULL)
{
for (; *Ptr; Ptr++)
- {
- if ((linklist_previous = calloc(1, sizeof(LK_ENTRY))) == NULL)
- return(1);
- memset(linklist_previous, '\0', sizeof(LK_ENTRY));
- linklist_previous->next = (*linklist_current);
- (*linklist_current) = linklist_previous;
-
- if (((*linklist_current)->attribute =
- calloc(1, strlen(Attribute) + 1)) == NULL)
- return(1);
- memset((*linklist_current)->attribute, '\0', strlen(Attribute) + 1);
- strcpy((*linklist_current)->attribute, Attribute);
- if (use_bervalue)
- {
- ber_length = (*(LDAP_BERVAL **)Ptr)->bv_len;
- if (((*linklist_current)->value = calloc(1, ber_length)) == NULL)
- return(1);
- memset((*linklist_current)->value, '\0', ber_length);
- memcpy((*linklist_current)->value,
- (*(LDAP_BERVAL **)Ptr)->bv_val, ber_length);
- (*linklist_current)->length = ber_length;
- }
- else
- {
- if (((*linklist_current)->value = calloc(1, strlen(*Ptr) + 1))
- == NULL)
- return(1);
- memset((*linklist_current)->value, '\0', strlen(*Ptr) + 1);
- (*linklist_current)->length = strlen(*Ptr);
- strcpy((*linklist_current)->value, *Ptr);
- }
- (*linklist_current)->ber_value = use_bervalue;
- if (((*linklist_current)->dn =
- calloc(1, strlen(distinguished_name) + 1)) == NULL)
- return(1);
- memset((*linklist_current)->dn, '\0',
- strlen(distinguished_name) + 1);
- strcpy((*linklist_current)->dn, distinguished_name);
-
+ {
+ if ((linklist_previous = calloc(1, sizeof(LK_ENTRY))) == NULL)
+ return(1);
+ memset(linklist_previous, '\0', sizeof(LK_ENTRY));
+ linklist_previous->next = (*linklist_current);
+ (*linklist_current) = linklist_previous;
+
+ if (((*linklist_current)->attribute = calloc(1,
+ strlen(Attribute) + 1)) == NULL)
+ return(1);
+ memset((*linklist_current)->attribute, '\0', strlen(Attribute) + 1);
+ strcpy((*linklist_current)->attribute, Attribute);
+ if (use_bervalue)
+ {
+ ber_length = (*(LDAP_BERVAL **)Ptr)->bv_len;
+ if (((*linklist_current)->value = calloc(1, ber_length)) == NULL)
+ return(1);
+ memset((*linklist_current)->value, '\0', ber_length);
+ memcpy((*linklist_current)->value, (*(LDAP_BERVAL **)Ptr)->bv_val,
+ ber_length);
+ (*linklist_current)->length = ber_length;
+ }
+ else
+ {
+ if (((*linklist_current)->value = calloc(1,
+ strlen(*Ptr) + 1)) == NULL)
+ return(1);
+ memset((*linklist_current)->value, '\0', strlen(*Ptr) + 1);
+ (*linklist_current)->length = strlen(*Ptr);
+ strcpy((*linklist_current)->value, *Ptr);
+ }
+ (*linklist_current)->ber_value = use_bervalue;
+ if (((*linklist_current)->dn = calloc(1,
+ strlen(distinguished_name) + 1)) == NULL)
+ return(1);
+ memset((*linklist_current)->dn, '\0', strlen(distinguished_name) + 1);
+ strcpy((*linklist_current)->dn, distinguished_name);
+
#ifdef LDAP_DEBUG
- if (!strcmp(Attribute, "objectGUID"))
- {
- guid = (GUID *)((*linklist_current)->value);
- sprintf(temp,
- "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
- guid->Data1, guid->Data2, guid->Data3,
- guid->Data4[0], guid->Data4[1], guid->Data4[2],
- guid->Data4[3], guid->Data4[4], guid->Data4[5],
- guid->Data4[6], guid->Data4[7]);
- print_to_screen(" %20s : {%s}\n", Attribute, temp);
- }
- else if (!strcmp(Attribute, "objectSid"))
- {
- sid = (SID *)((*(LDAP_BERVAL **)Ptr)->bv_val);
+ if (!strcmp(Attribute, "objectGUID"))
+ {
+ guid = (GUID *)((*linklist_current)->value);
+ sprintf(temp, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+ guid->Data1, guid->Data2, guid->Data3,
+ guid->Data4[0], guid->Data4[1], guid->Data4[2],
+ guid->Data4[3], guid->Data4[4], guid->Data4[5],
+ guid->Data4[6], guid->Data4[7]);
+ print_to_screen(" %20s : {%s}\n", Attribute, temp);
+ }
+ else if (!strcmp(Attribute, "objectSid"))
+ {
+ sid = (SID *)((*(LDAP_BERVAL **)Ptr)->bv_val);
#ifdef _WIN32
- print_to_screen(" Revision = %d\n", sid->Revision);
- print_to_screen(" SID Identifier Authority:\n");
- sid_auth = &sid->IdentifierAuthority;
- if (sid_auth->Value[0])
- print_to_screen(" SECURITY_NULL_SID_AUTHORITY\n");
- else if (sid_auth->Value[1])
- print_to_screen(" SECURITY_WORLD_SID_AUTHORITY\n");
- else if (sid_auth->Value[2])
- print_to_screen(" SECURITY_LOCAL_SID_AUTHORITY\n");
- else if (sid_auth->Value[3])
- print_to_screen(" SECURITY_CREATOR_SID_AUTHORITY\n");
- else if (sid_auth->Value[5])
- print_to_screen(" SECURITY_NT_AUTHORITY\n");
- else
- print_to_screen(" UNKNOWN SID AUTHORITY\n");
- subauth_count = GetSidSubAuthorityCount(sid);
- print_to_screen(" SidSubAuthorityCount = %d\n",
- *subauth_count);
- print_to_screen(" SidSubAuthority:\n");
- for (i = 0; i < *subauth_count; i++)
- {
- if ((subauth = GetSidSubAuthority(sid, i)) != NULL)
- print_to_screen(" %u\n", *subauth);
- }
+ print_to_screen(" Revision = %d\n", sid->Revision);
+ print_to_screen(" SID Identifier Authority:\n");
+ sid_auth = &sid->IdentifierAuthority;
+ if (sid_auth->Value[0])
+ print_to_screen(" SECURITY_NULL_SID_AUTHORITY\n");
+ else if (sid_auth->Value[1])
+ print_to_screen(" SECURITY_WORLD_SID_AUTHORITY\n");
+ else if (sid_auth->Value[2])
+ print_to_screen(" SECURITY_LOCAL_SID_AUTHORITY\n");
+ else if (sid_auth->Value[3])
+ print_to_screen(" SECURITY_CREATOR_SID_AUTHORITY\n");
+ else if (sid_auth->Value[5])
+ print_to_screen(" SECURITY_NT_AUTHORITY\n");
+ else
+ print_to_screen(" UNKNOWN SID AUTHORITY\n");
+ subauth_count = GetSidSubAuthorityCount(sid);
+ print_to_screen(" SidSubAuthorityCount = %d\n",
+ *subauth_count);
+ print_to_screen(" SidSubAuthority:\n");
+ for (i = 0; i < *subauth_count; i++)
+ {
+ if ((subauth = GetSidSubAuthority(sid, i)) != NULL)
+ print_to_screen(" %u\n", *subauth);
+ }
#endif
- }
- else if ((!memcmp(Attribute, "userAccountControl",
- strlen("userAccountControl"))) ||
- (!memcmp(Attribute, "sAMAccountType",
- strlen("sAmAccountType"))))
- {
- intValue = atoi(*Ptr);
- print_to_screen(" %20s : %ld\n",Attribute, intValue);
- if (!memcmp(Attribute, "userAccountControl",
- strlen("userAccountControl")))
- {
- if (intValue & UF_ACCOUNTDISABLE)
- print_to_screen(" %20s : %s\n", "",
- "Account disabled");
- else
- print_to_screen(" %20s : %s\n", "",
- "Account active");
- if (intValue & UF_HOMEDIR_REQUIRED)
- print_to_screen(" %20s : %s\n", "",
- "Home directory required");
- if (intValue & UF_LOCKOUT)
- print_to_screen(" %20s : %s\n", "",
- "Account locked out");
- if (intValue & UF_PASSWD_NOTREQD)
- print_to_screen(" %20s : %s\n", "",
- "No password required");
- if (intValue & UF_PASSWD_CANT_CHANGE)
- print_to_screen(" %20s : %s\n", "",
- "Cannot change password");
- if (intValue & UF_TEMP_DUPLICATE_ACCOUNT)
- print_to_screen(" %20s : %s\n", "",
- "Temp duplicate account");
- if (intValue & UF_NORMAL_ACCOUNT)
- print_to_screen(" %20s : %s\n", "",
- "Normal account");
- if (intValue & UF_INTERDOMAIN_TRUST_ACCOUNT)
- print_to_screen(" %20s : %s\n", "",
- "Interdomain trust account");
- if (intValue & UF_WORKSTATION_TRUST_ACCOUNT)
- print_to_screen(" %20s : %s\n", "",
- "Workstation trust account");
- if (intValue & UF_SERVER_TRUST_ACCOUNT)
- print_to_screen(" %20s : %s\n", "",
- "Server trust account");
- }
- }
- else
- {
- print_to_screen(" %20s : %s\n",Attribute, *Ptr);
- }
+ }
+ else if ((!memcmp(Attribute, "userAccountControl",
+ strlen("userAccountControl"))) ||
+ (!memcmp(Attribute, "sAMAccountType",
+ strlen("sAmAccountType"))))
+ {
+ intValue = atoi(*Ptr);
+ print_to_screen(" %20s : %ld\n",Attribute, intValue);
+ if (!memcmp(Attribute, "userAccountControl",
+ strlen("userAccountControl")))
+ {
+ if (intValue & UF_ACCOUNTDISABLE)
+ print_to_screen(" %20s : %s\n",
+ "", "Account disabled");
+ else
+ print_to_screen(" %20s : %s\n",
+ "", "Account active");
+ if (intValue & UF_HOMEDIR_REQUIRED)
+ print_to_screen(" %20s : %s\n",
+ "", "Home directory required");
+ if (intValue & UF_LOCKOUT)
+ print_to_screen(" %20s : %s\n",
+ "", "Account locked out");
+ if (intValue & UF_PASSWD_NOTREQD)
+ print_to_screen(" %20s : %s\n",
+ "", "No password required");
+ if (intValue & UF_PASSWD_CANT_CHANGE)
+ print_to_screen(" %20s : %s\n",
+ "", "Cannot change password");
+ if (intValue & UF_TEMP_DUPLICATE_ACCOUNT)
+ print_to_screen(" %20s : %s\n",
+ "", "Temp duplicate account");
+ if (intValue & UF_NORMAL_ACCOUNT)
+ print_to_screen(" %20s : %s\n",
+ "", "Normal account");
+ if (intValue & UF_INTERDOMAIN_TRUST_ACCOUNT)
+ print_to_screen(" %20s : %s\n",
+ "", "Interdomain trust account");
+ if (intValue & UF_WORKSTATION_TRUST_ACCOUNT)
+ print_to_screen(" %20s : %s\n",
+ "", "Workstation trust account");
+ if (intValue & UF_SERVER_TRUST_ACCOUNT)
+ print_to_screen(" %20s : %s\n",
+ "", "Server trust account");
+ }
+ }
+ else
+ {
+ print_to_screen(" %20s : %s\n",Attribute, *Ptr);
+ }
#endif /*LDAP_DEBUG*/
- }
+ }
if (str_value != NULL)
- ldap_value_free(str_value);
+ ldap_value_free(str_value);
if (ber_value != NULL)
- ldap_value_free_len(ber_value);
+ ldap_value_free_len(ber_value);
}
(*linklist_current) = linklist_previous;
return(0);
}
-int add_user_lists(int ac, char **av, void *user)
-{
- if (atoi(av[L_ACTIVE]) && atoi(av[L_GROUP])) /* active group ? */
- edit_group(1, av[L_NAME], "USER", user, NULL, NULL, NULL);
- return 0;
-}
-
-void edit_group(int op, char *group, char *type, char *member,
- LDAP *ldap_handle, char *dn_path, char *ldap_hostname)
-{
- ULONG rc;
- char *p = 0;
- char search_exp[128];
- static char local_realm[REALM_SZ+1] = "";
- LK_ENTRY *linklist;
- LDAPMessage *ldap_entry;
-
- /* The following KERBEROS rc allows for the use of entities
- * user@foreign_cell.
- */
- if (!local_realm[0])
- krb_get_lrealm(local_realm, 1);
- if (!strcmp(type, "KERBEROS"))
- {
- p = (char *)strchr(member, '@');
- if (p && !strcasecmp(p+1, local_realm))
- *p = 0;
- }
- else if (strcmp(type, "USER"))
- return; /* invalid type */
-
- /* Cannot risk doing another query during a callback */
- /* We could do this simply for type USER, but eventually this may also
- * dynamically add KERBEROS types to the prdb, and we will need to do
- * a query to look up the uid of the null-instance user
- */
- if (mr_connections)
- {
- linklist = calloc(1, sizeof(LK_ENTRY));
- if (!linklist)
- {
- critical_alert("incremental", "Out of memory");
- exit(1);
- }
- memset(linklist, '\0', sizeof(LK_ENTRY));
- linklist->op = op;
- linklist->dn = NULL;
- linklist->list = calloc(1, strlen(group) + 1);
- memset(linklist->list, '\0', strlen(group) + 1);
- strcpy(linklist->list, group);
- linklist->type = calloc(1, strlen(type) + 1);
- memset(linklist->type, '\0', strlen(type) + 1);
- strcpy(linklist->type, type);
- linklist->member = calloc(1, strlen(member) + 1);
- memset(linklist->member, '\0', strlen(member) + 1);
- strcpy(linklist->member, member);
- linklist->next = member_base;
- member_base = linklist;
- return;
- }
-
- com_err(whoami, 0, "%s %s %s group %s", (op ? "Adding" : "Removing"),
- member, (op ? "to" : "from"), group);
- sprintf(search_exp, "(sAMAccountName=%s)", member);
- if ((rc = ldap_search_s(ldap_handle, dn_path, LDAP_SCOPE_SUBTREE,
- search_exp, NULL, 0, &ldap_entry)) != LDAP_SUCCESS)
- {
- critical_alert("incremental", "Couldn't %s %s %s %s",
- op ? "add" : "remove", member,
- op ? "to" : "from", group);
- rc = ldap_msgfree(ldap_entry);
- return;
- }
- linklist = calloc(1, sizeof(LK_ENTRY));
- if (!linklist)
- {
- critical_alert("incremental", "Out of memory");
- exit(1);
- }
- memset(linklist, '\0', sizeof(LK_ENTRY));
- linklist->op = op;
- linklist->dn = NULL;
- linklist->list = calloc(1, strlen(group) + 1);
- memset(linklist->list, '\0', strlen(group) + 1);
- strcpy(linklist->list, group);
- linklist->type = calloc(1, strlen(type) + 1);
- memset(linklist->type, '\0', strlen(type) + 1);
- strcpy(linklist->type, type);
- linklist->member = calloc(1, strlen(member) + 1);
- memset(linklist->member, '\0', strlen(member) + 1);
- strcpy(linklist->member, member);
- linklist->next = NULL;
-
- rc = member_update(ldap_handle, dn_path, ldap_entry, member, NULL,
- ldap_hostname, op ? MEMBER_ADD : MEMBER_REMOVE, linklist);
- if (rc)
- {
- critical_alert("incremental", "Couldn't %s %s %s %s: %s",
- op ? "add" : "remove", member,
- op ? "to" : "from", group);
- }
-
- linklist_free(linklist);
- rc = ldap_msgfree(ldap_entry);
- /*
- * rc = pr_try(op ? pr_AddToGroup : pr_RemoveUserFromGroup, member, buf);
- * if (rc)
- * {
- * if (op==1 && rc == PRIDEXIST)
- * return;
- * if (rc == PRNOENT)
- * {
- * if (op == 0)
- * return;
- * if (!strcmp(type, "KERBEROS"))
- * return;
- * rc = moira_connect();
- * if (!rc)
- * {
- * rc = mr_query("get_user_by_login", 1, &member,
- * (void *)check_user, (char *) &ustate);
- * }
- * if (rc)
- * {
- * critical_alert("incremental", "Error contacting Moira server "
- * "to lookup user %s: %s", member,
- * error_message(rc));
- * }
- * mr_disconnect();
- * mr_connections--;
- * if (!rc && ustate!=1 && ustate!=2)
- * return;
- * rc = PRNOENT;
- * }
- * critical_alert("incremental", "Couldn't %s %s %s %s: %s",
- * op ? "add" : "remove", member,
- * op ? "to" : "from", buf,
- * error_message(rc));
- * }
- */
-}
-
int moira_connect(void)
{
- long rc;
- char HostName[64];
-
+ long rc;
+ char HostName[64];
+
if (!mr_connections++)
{
#ifdef _WIN32
memset(HostName, '\0', sizeof(HostName));
strcpy(HostName, "ttsp");
+ rc = mr_connect_cl(HostName, "winad.incr", QUERY_VERSION, 1);
+/*det
rc = mr_connect(HostName);
+*/
#else
struct utsname uts;
uname(&uts);
+ rc = mr_connect_cl(uts.nodename, "winad.incr", QUERY_VERSION, 1);
+/*
rc = mr_connect(uts.nodename);
+*/
#endif /*WIN32*/
+/*det
if (!rc)
- rc = mr_auth("afs.incr");
+ rc = mr_auth("winad.incr");
+*/
return rc;
}
return 0;
int moira_disconnect(void)
{
- if (!--mr_connections)
- mr_disconnect();
- return 0;
-}
-
-int add_list_members(int ac, char **av, void *group)
-{
- edit_group(1, group, av[0], av[1], NULL, NULL, NULL);
- return 0;
-}
-int check_user(int ac, char **av, void *ustate)
-{
- *(int *)ustate = atoi(av[U_STATE]);
- return 0;
-}
-
-void free_values(int newvalue_count, LDAPMod **newvalue_array,
- char ***modvalues)
-{
- int i, j;
-
- if (newvalue_array != NULL)
- {
- i = 0;
- while (newvalue_array[i] != NULL)
- {
- free(newvalue_array[i]);
- newvalue_array[i]= NULL;
- ++i;
- }
- free(newvalue_array);
- newvalue_array = NULL;
- }
- if (modvalues != NULL)
- {
- i = 0;
- while (modvalues[i] != NULL)
- {
- j = 0;
- while (modvalues[i][j] != NULL)
- {
- free(modvalues[i][j]);
- modvalues[i][j] = NULL;
- ++j;
- }
- free(modvalues[i]);
- modvalues[i] = NULL;
- ++i;
- }
- free(modvalues);
- modvalues = NULL;
- }
-}
-
-void linklist_free(LK_ENTRY *linklist_base)
-{
- LK_ENTRY *linklist_previous;
-
- while (linklist_base != NULL)
+ if (!--mr_connections)
{
- if (linklist_base->dn != NULL)
- free(linklist_base->dn);
- if (linklist_base->attribute != NULL)
- free(linklist_base->attribute);
- if (linklist_base->value != NULL)
- free(linklist_base->value);
- if (linklist_base->member != NULL)
- free(linklist_base->member);
- if (linklist_base->type != NULL)
- free(linklist_base->type);
- if (linklist_base->list != NULL)
- free(linklist_base->list);
- linklist_previous = linklist_base;
- linklist_base = linklist_previous->next;
- free(linklist_previous);
+ mr_disconnect();
}
+ return 0;
}
int convert_domain_to_dn(char *domain, char **dnp)
{
- char *fp, *dp;
- char dn[1024];
- int dnlen = 1;
-
+ char *fp;
+ char *dp;
+ char dn[1024];
+ int dnlen = 1;
+
memset(dn, 0, sizeof(dn));
strcpy(dn, "dc=");
dp = dn+3;
for (fp = domain; *fp; fp++)
{
if (*fp == '.')
- {
- strcpy(dp, ",dc=");
- dp += 4;
- }
+ {
+ strcpy(dp, ",dc=");
+ dp += 4;
+ }
else
- *dp++ = *fp;
+ *dp++ = *fp;
}
-
+
*dnp = (char *)strdup(dn);
return 0;
}
void get_distinguished_name(LDAP *ldap_handle, LDAPMessage *ldap_entry,
- char *distinguished_name)
+ char *distinguished_name)
{
- char *CName;
-
+ char *CName;
+
CName = ldap_get_dn(ldap_handle, ldap_entry);
if (CName == NULL)
return;
}
int linklist_create_entry(char *attribute, char *value,
- LK_ENTRY **linklist_entry)
+ LK_ENTRY **linklist_entry)
{
(*linklist_entry) = calloc(1, sizeof(LK_ENTRY));
if (!(*linklist_entry))
void print_to_screen(const char *fmt, ...)
{
va_list pvar;
-
+
va_start(pvar, fmt);
vfprintf(stderr, fmt, pvar);
fflush(stderr);
va_end(pvar);
}
+
+int get_group_membership(char *group_membership, char *group_ou,
+ int *security_flag, char **av)
+{
+ int maillist_flag;
+ int group_flag;
+
+ maillist_flag = atoi(av[L_MAILLIST]);
+ group_flag = atoi(av[L_GROUP]);
+ if (security_flag != NULL)
+ (*security_flag) = 0;
+
+ if ((maillist_flag) && (group_flag))
+ {
+ if (group_membership != NULL)
+ group_membership[0] = 'B';
+ if (security_flag != NULL)
+ (*security_flag) = 1;
+ if (group_ou != NULL)
+ strcpy(group_ou, group_ou_both);
+ }
+ else if ((!maillist_flag) && (group_flag))
+ {
+ if (group_membership != NULL)
+ group_membership[0] = 'S';
+ if (security_flag != NULL)
+ (*security_flag) = 1;
+ if (group_ou != NULL)
+ strcpy(group_ou, group_ou_security);
+ }
+ else if ((maillist_flag) && (!group_flag))
+ {
+ if (group_membership != NULL)
+ group_membership[0] = 'D';
+ if (group_ou != NULL)
+ strcpy(group_ou, group_ou_distribution);
+ }
+ else
+ {
+ if (group_membership != NULL)
+ group_membership[0] = 'N';
+ if (group_ou != NULL)
+ strcpy(group_ou, group_ou_neither);
+ }
+ return(0);
+}
+
+int get_group_info(int ac, char**av, void *ptr)
+{
+ char **call_args;
+
+ call_args = ptr;
+
+ if (!atoi(av[L_ACTIVE]))
+ return(0);
+ if (ptr == NULL)
+ get_group_membership(GroupType, NULL, NULL, av);
+ else
+ get_group_membership(call_args[4], call_args[3], NULL, av);
+
+ return(0);
+}
+
+int group_create(int ac, char **av, void *ptr)
+{
+ LDAPMod *mods[20];
+ char new_dn[256];
+ char group_ou[256];
+ char new_group_name[256];
+ char sam_group_name[256];
+ char cn_group_name[256];
+ char *cn_v[] = {NULL, NULL};
+ char *objectClass_v[] = {"top", "group", NULL};
+ char info[256];
+ char *samAccountName_v[] = {NULL, NULL};
+ char *managedBy_v[] = {NULL, NULL};
+ char *altSecurityIdentities_v[] = {NULL, NULL};
+ char *name_v[] = {NULL, NULL};
+ char *desc_v[] = {NULL, NULL};
+ char *info_v[] = {NULL, NULL};
+ char *groupTypeControl_v[] = {NULL, NULL};
+ char groupTypeControlStr[80];
+ char group_membership[1];
+ int i;
+ int security_flag;
+ u_int groupTypeControl = ADS_GROUP_TYPE_GLOBAL_GROUP;
+ int n;
+ int rc;
+ int sid_count;
+ char filter_exp[256];
+ char *attr_array[3];
+ char **call_args;
+
+ call_args = ptr;
+
+ if (!atoi(av[L_ACTIVE]))
+ return(0);
+ if (!check_string(av[L_NAME]))
+ return(0);
+ memset(group_ou, 0, sizeof(group_ou));
+ memset(group_membership, 0, sizeof(group_membership));
+ security_flag = 0;
+ get_group_membership(group_membership, group_ou, &security_flag, av);
+ call_args[3] = strdup(group_ou);
+ call_args[4] = strdup(group_membership);
+
+ if (security_flag)
+ groupTypeControl |= ADS_GROUP_TYPE_SECURITY_ENABLED;
+ sprintf(groupTypeControlStr, "%ld", groupTypeControl);
+ groupTypeControl_v[0] = groupTypeControlStr;
+
+ strcpy(new_group_name, av[L_NAME]);
+ strcpy(sam_group_name, av[L_NAME]);
+ strcpy(cn_group_name, av[L_NAME]);
+ sprintf(&sam_group_name[strlen(sam_group_name)],
+ "_zZx%c", group_membership[0]);
+
+ samAccountName_v[0] = sam_group_name;
+ name_v[0] = new_group_name;
+ cn_v[0] = cn_group_name;
+
+ sprintf(new_dn, "cn=%s,%s,%s", cn_group_name, group_ou, call_args[1]);
+ n = 0;
+ ADD_ATTR("cn", cn_v, LDAP_MOD_ADD);
+ ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
+ ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_ADD);
+ ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
+ ADD_ATTR("name", name_v, LDAP_MOD_ADD);
+ if (strlen(av[L_DESC]) != 0)
+ {
+ desc_v[0] = av[L_DESC];
+ ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
+ }
+ ADD_ATTR("groupType", groupTypeControl_v, LDAP_MOD_ADD);
+ if (!strcmp(av[L_ACE_TYPE], "LIST"))
+ {
+ sprintf(info, "The Administrator of this list is the LIST: %s", av[L_ACE_NAME]);
+ info_v[0] = info;
+ ADD_ATTR("info", info_v, LDAP_MOD_ADD);
+ }
+ mods[n] = NULL;
+
+ rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
+
+ for (i = 0; i < n; i++)
+ free(mods[i]);
+ if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
+ return(rc);
+ sprintf(filter_exp, "(sAMAccountName=%s)", sam_group_name);
+ attr_array[0] = "objectSid";
+ attr_array[1] = NULL;
+ sid_count = 0;
+ if ((rc = linklist_build((LDAP *)call_args[0], call_args[1], filter_exp, attr_array,
+ sid_ptr, &sid_count)) == LDAP_SUCCESS)
+ {
+ if (sid_count == 1)
+ {
+ (*sid_ptr)->member = strdup(av[L_NAME]);
+ (*sid_ptr)->type = (char *)GROUPS;
+ sid_ptr = &(*sid_ptr)->next;
+ }
+ }
+ return(LDAP_SUCCESS);
+}
+
+int group_delete(int ac, char **av, void *ptr)
+{
+ LK_ENTRY *group_base;
+ char **call_args;
+ char *attr_array[3];
+ char filter_exp[1024];
+ char group_membership[1];
+ char group_ou[256];
+ char sam_group_name[256];
+ int security_flag;
+ int group_count;
+ int rc;
+
+ call_args = ptr;
+
+ if (!check_string(av[L_NAME]))
+ return(0);
+ memset(group_ou, 0, sizeof(group_ou));
+ memset(group_membership, 0, sizeof(group_membership));
+ security_flag = 0;
+ get_group_membership(group_membership, group_ou, &security_flag, av);
+
+ group_count = 0;
+ group_base = NULL;
+ attr_array[0] = "distinguishedName";
+ attr_array[1] = NULL;
+ strcpy(sam_group_name, av[L_NAME]);
+ sprintf(&sam_group_name[strlen(sam_group_name)], "_zZx%c",
+ group_membership[0]);
+ sprintf(filter_exp, "(sAMAccountName=%s)", sam_group_name);
+ if ((rc = linklist_build((LDAP *)call_args[0], call_args[1], filter_exp,
+ attr_array, &group_base, &group_count)) != 0)
+ goto cleanup;
+ if (group_count == 1)
+ rc = ldap_delete_s((LDAP *)call_args[0], group_base->value);
+ if (rc != LDAP_SUCCESS)
+ {
+ critical_alert("AD incremental",
+ "Couldn't delete group %s: %s",
+ av[L_NAME], ldap_err2string(rc));
+ }
+cleanup:
+ linklist_free(group_base);
+ return(rc);
+}
+
+int group_ad_delete(LDAP *ldap_handle, char *dn_path, char *group_name)
+{
+ LK_ENTRY *group_base;
+ char *attr_array[3];
+ char filter_exp[1024];
+ char sam_group_name[256];
+ char temp[512];
+ int group_count;
+ int rc;
+
+ if (!check_string(group_name))
+ return(0);
+
+ rc = 1;
+ group_count = 0;
+ group_base = NULL;
+ attr_array[0] = "distinguishedName";
+ attr_array[1] = NULL;
+ strcpy(sam_group_name, group_name);
+ sprintf(temp, "%s,%s", group_ou_root, dn_path);
+ sprintf(filter_exp, "(sAMAccountName=%s_zZx*)", sam_group_name);
+ if (linklist_build(ldap_handle, temp, filter_exp, attr_array,
+ &group_base, &group_count) != 0)
+ goto cleanup;
+ if (group_count == 1)
+ {
+ rc = ldap_delete_s(ldap_handle, group_base->value);
+ if (rc != LDAP_SUCCESS)
+ {
+ critical_alert("AD incremental",
+ "Couldn't delete group %s",
+ group_name);
+ }
+ }
+cleanup:
+ linklist_free(group_base);
+ return(rc);
+}
+
+int group_list_build(int ac, char **av, void *ptr)
+{
+ LK_ENTRY *linklist;
+ char **call_args;
+
+ call_args = ptr;
+
+ if (!atoi(av[L_ACTIVE]))
+ return(0);
+ if (!check_string(av[L_NAME]))
+ return(0);
+ linklist = calloc(1, sizeof(LK_ENTRY));
+ if (!linklist)
+ {
+ critical_alert("AD incremental", "Out of memory");
+ exit(1);
+ }
+ memset(linklist, '\0', sizeof(LK_ENTRY));
+ linklist->op = 1;
+ linklist->dn = NULL;
+ linklist->list = calloc(1, strlen(av[L_NAME]) + 1);
+ strcpy(linklist->list, av[L_NAME]);
+ linklist->type = calloc(1, strlen("USER") + 1);
+ strcpy(linklist->type, "USER");
+ linklist->member = calloc(1, strlen(call_args[0]) + 1);
+ strcpy(linklist->member, call_args[0]);
+ linklist->next = member_base;
+ member_base = linklist;
+ return(0);
+}
+
+int member_list_build(int ac, char **av, void *ptr)
+{
+ LK_ENTRY *linklist;
+ char temp[128];
+ char **call_args;
+
+ call_args = ptr;
+
+ strcpy(temp, av[ACE_NAME]);
+ if (!check_string(temp))
+ return(0);
+ if (!strcmp(av[ACE_TYPE], "STRING"))
+ {
+ contact_create((LDAP *)call_args[0], call_args[1], temp, contact_ou);
+ }
+ else if (!strcmp(av[ACE_TYPE], "LIST"))
+ {
+ strcpy(temp, av[ACE_NAME]);
+ }
+ else if (strcmp(av[ACE_TYPE], "USER"))
+ {
+ contact_create((LDAP *)call_args[0], call_args[1], temp, kerberos_ou);
+ }
+ linklist = member_base;
+ while (linklist)
+ {
+ if (!strcasecmp(temp, linklist->member))
+ return(0);
+ linklist = linklist->next;
+ }
+ linklist = calloc(1, sizeof(LK_ENTRY));
+ linklist->op = 1;
+ linklist->dn = NULL;
+ linklist->list = calloc(1, strlen(call_args[2]) + 1);
+ strcpy(linklist->list, call_args[2]);
+ linklist->type = calloc(1, strlen(av[ACE_TYPE]) + 1);
+ strcpy(linklist->type, av[ACE_TYPE]);
+ linklist->member = calloc(1, strlen(temp) + 1);
+ strcpy(linklist->member, temp);
+ linklist->next = member_base;
+ member_base = linklist;
+ return(0);
+}
+
+#define USER_COUNT 5
+
+int member_list_process(LDAP *ldap_handle, char *dn_path, char *group_name,
+ char *group_ou, char *group_membership)
+{
+ char distinguished_name[1024];
+ char **modvalues;
+ char filter_exp[4096];
+ char *attr_array[3];
+ char temp[256];
+ char group_member[256];
+ char *args[2];
+ int group_count;
+ int new_list_count;
+ int i;
+ int j;
+ int k;
+ int n;
+ int filter_count;
+ LDAPMod *mods[20];
+ LK_ENTRY *group_base;
+ LK_ENTRY *new_list;
+ LK_ENTRY *sPtr;
+ LK_ENTRY *pPtr;
+ ULONG rc;
+
+ rc = 0;
+ group_base = NULL;
+ group_count = 0;
+ modvalues = NULL;
+
+ pPtr = member_base;
+ while (pPtr)
+ {
+ ++group_count;
+ pPtr = pPtr->next;
+ }
+ j = group_count/USER_COUNT;
+ ++j;
+
+ if (!check_string(group_name))
+ return(0);
+ strcpy(temp, group_name);
+ sprintf(filter_exp, "(sAMAccountName=%s_zZx%c)", temp, group_membership[0]);
+ attr_array[0] = "distinguishedName";
+ attr_array[1] = NULL;
+ if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array,
+ &group_base, &group_count)) != 0)
+ {
+ critical_alert("AD incremental",
+ "LDAP server unable to get group %s info: %d",
+ group_name, rc);
+ rc = 1;
+ goto cleanup;
+ }
+ if (group_count != 1)
+ {
+ critical_alert("AD incremental",
+ "LDAP server unable to find group %s in AD.",
+ group_name);
+ rc = 1;
+ goto cleanup;
+ }
+ strcpy(distinguished_name, group_base->value);
+ linklist_free(group_base);
+ group_base = NULL;
+ group_count = 0;
+
+ pPtr = member_base;
+ for (i = 0; i < j; i++)
+ {
+ if (pPtr == NULL)
+ break;
+ memset(filter_exp, 0, sizeof(filter_exp));
+ strcpy(filter_exp, "(|");
+ filter_count = 0;
+ for (k = 0; k < USER_COUNT; k++)
+ {
+ strcpy(group_member, pPtr->member);
+ if (!check_string(group_member))
+ {
+ pPtr = pPtr->next;
+ if (pPtr == NULL)
+ break;
+ continue;
+ }
+ if (!strcmp(pPtr->type, "LIST"))
+ {
+ args[0] = pPtr->member;
+ rc = mr_query("get_list_info", 1, args, get_group_info, NULL);
+ sprintf(temp, "(sAMAccountName=%s_zZx%c)", group_member,
+ GroupType[0]);
+ }
+ else if (!strcmp(pPtr->type, "USER"))
+ {
+ sprintf(temp, "(sAMAccountName=%s)", group_member);
+ }
+ else if (!strcmp(pPtr->type, "STRING"))
+ {
+ sprintf(temp, "(cn=%s,%s,%s)", group_member, contact_ou, dn_path);
+ }
+ else
+ {
+ sprintf(temp, "(cn=%s,%s,%s)", group_member, kerberos_ou, dn_path);
+ }
+ strcat(filter_exp, temp);
+ ++filter_count;
+ pPtr = pPtr->next;
+ if (pPtr == NULL)
+ break;
+ }
+ if (filter_count == 0)
+ continue;
+ strcat(filter_exp, ")");
+ attr_array[0] = "distinguishedName";
+ attr_array[1] = NULL;
+ new_list = NULL;
+ new_list_count = 0;
+ if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array,
+ &new_list, &new_list_count)) != 0)
+ {
+ critical_alert("AD incremental",
+ "LDAP server unable to get group %s members from AD: %d",
+ group_name, rc);
+ rc = 1;
+ goto cleanup;
+ }
+ group_count += new_list_count;
+ if (group_base == NULL)
+ group_base = new_list;
+ else
+ {
+ sPtr = group_base;
+ while (sPtr)
+ {
+ if (sPtr->next != NULL)
+ {
+ sPtr = sPtr->next;
+ continue;
+ }
+ sPtr->next = new_list;
+ break;
+ }
+ }
+ }
+
+ modvalues = NULL;
+ if (group_count != 0)
+ {
+ if ((rc = construct_newvalues(group_base, group_count, NULL, NULL,
+ &modvalues, REPLACE)) == 1)
+ goto cleanup;
+ n = 0;
+ ADD_ATTR("member", modvalues, LDAP_MOD_ADD);
+ mods[n] = NULL;
+ if ((rc = ldap_modify_s(ldap_handle, distinguished_name, mods))
+ != LDAP_SUCCESS)
+ {
+ mods[0]->mod_op = LDAP_MOD_REPLACE;
+ rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
+ }
+ if (rc == LDAP_ALREADY_EXISTS)
+ rc = LDAP_SUCCESS;
+ for (i = 0; i < n; i++)
+ free(mods[i]);
+ linklist_free(group_base);
+ group_count = 0;
+ group_base = NULL;
+ }
+
+cleanup:
+ free_values(modvalues);
+ linklist_free(group_base);
+ return(rc);
+}
+
+int contact_create(LDAP *ld, char *bind_path, char *user, char *group_ou)
+{
+ LDAPMod *mods[20];
+ char new_dn[256];
+ char cn_user_name[256];
+ char contact_name[256];
+ char *cn_v[] = {NULL, NULL};
+ char *contact_v[] = {NULL, NULL};
+ char *objectClass_v[] = {"top", "person",
+ "organizationalPerson",
+ "contact", NULL};
+ char *name_v[] = {NULL, NULL};
+ char *desc_v[] = {NULL, NULL};
+ int n;
+ int rc;
+ int i;
+
+ if (!check_string(user))
+ return(0);
+ strcpy(contact_name, user);
+ sprintf(cn_user_name,"CN=%s,%s,%s", contact_name, group_ou, bind_path);
+ cn_v[0] = cn_user_name;
+ contact_v[0] = contact_name;
+ name_v[0] = user;
+ desc_v[0] = "Auto account created by Moira";
+
+ strcpy(new_dn, cn_user_name);
+ n = 0;
+ ADD_ATTR("cn", contact_v, LDAP_MOD_ADD);
+ ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
+ ADD_ATTR("name", name_v, LDAP_MOD_ADD);
+ ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
+ ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
+ mods[n] = NULL;
+
+ rc = ldap_add_ext_s(ld, new_dn, mods, NULL, NULL);
+ for (i = 0; i < n; i++)
+ free(mods[i]);
+ if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
+ return(rc);
+ return(LDAP_SUCCESS);
+}
+
+int user_create(int ac, char **av, void *ptr)
+{
+ LDAPMod *mods[20];
+ char new_dn[256];
+ char user_name[256];
+ char *cn_v[] = {NULL, NULL};
+ char *objectClass_v[] = {"top", "person",
+ "organizationalPerson",
+ "user", NULL};
+
+ char *samAccountName_v[] = {NULL, NULL};
+ char *altSecurityIdentities_v[] = {NULL, NULL};
+ char *name_v[] = {NULL, NULL};
+ char *desc_v[] = {NULL, NULL};
+ char upn[256];
+ char *userPrincipalName_v[] = {NULL, NULL};
+ char *userAccountControl_v[] = {NULL, NULL};
+ char userAccountControlStr[80];
+ char temp[128];
+ u_int userAccountControl = UF_NORMAL_ACCOUNT | UF_DONT_EXPIRE_PASSWD | UF_PASSWD_CANT_CHANGE;
+ int n;
+ int rc;
+ int i;
+ int sid_count;
+ char filter_exp[256];
+ char *attr_array[3];
+ char **call_args;
+
+ call_args = ptr;
+
+ if (!check_string(av[U_NAME]))
+ return(0);
+ if ((atoi(av[U_STATE]) != US_REGISTERED) && (atoi(av[U_STATE]) != US_NO_PASSWD) &&
+ (atoi(av[U_STATE]) != US_ENROLL_NOT_ALLOWED))
+ if (!strncmp(av[U_NAME], "#", 1))
+ return(0);
+ strcpy(user_name, av[U_NAME]);
+ sprintf(upn, "%s@%s", user_name, ldap_domain);
+ samAccountName_v[0] = user_name;
+ if (atoi(av[U_STATE]) == US_DELETED)
+ userAccountControl |= UF_ACCOUNTDISABLE;
+ sprintf(userAccountControlStr, "%ld", userAccountControl);
+ userAccountControl_v[0] = userAccountControlStr;
+ userPrincipalName_v[0] = upn;
+
+ cn_v[0] = user_name;
+ name_v[0] = user_name;
+ desc_v[0] = "Auto account created by Moira";
+ sprintf(temp, "Kerberos:%s@%s", user_name, PRIMARY_REALM);
+ altSecurityIdentities_v[0] = temp;
+ sprintf(new_dn, "cn=%s,%s,%s", user_name, user_ou, call_args[1]);
+
+ n = 0;
+ ADD_ATTR("cn", cn_v, LDAP_MOD_ADD);
+ ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
+ ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_ADD);
+ ADD_ATTR("userPrincipalName", userPrincipalName_v, LDAP_MOD_ADD);
+ ADD_ATTR("userAccountControl", userAccountControl_v, LDAP_MOD_ADD);
+ ADD_ATTR("name", name_v, LDAP_MOD_ADD);
+ ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
+ ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
+ ADD_ATTR("altSecurityIdentities", altSecurityIdentities_v, LDAP_MOD_ADD);
+ mods[n] = NULL;
+
+ rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
+ for (i = 0; i < n; i++)
+ free(mods[i]);
+ if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
+ return(rc);
+ if (rc == LDAP_SUCCESS)
+ {
+ if ((rc = set_password(user_name, ldap_domain)) != 0)
+ {
+ critical_alert("AD incremental", "Couldn't set password for user %s",
+ user_name);
+ return(rc);
+ }
+ }
+ sprintf(filter_exp, "(sAMAccountName=%s)", user_name);
+ attr_array[0] = "objectSid";
+ attr_array[1] = NULL;
+ sid_count = 0;
+ if ((rc = linklist_build((LDAP *)call_args[0], call_args[1], filter_exp, attr_array,
+ sid_ptr, &sid_count)) == LDAP_SUCCESS)
+ {
+ if (sid_count == 1)
+ {
+ (*sid_ptr)->member = strdup(av[U_NAME]);
+ (*sid_ptr)->type = (char *)USERS;
+ sid_ptr = &(*sid_ptr)->next;
+ }
+ }
+ return(LDAP_SUCCESS);
+ return(LDAP_SUCCESS);
+}
+
+int group_update_membership(LDAP *ldap_handle, char *dn_path, char *group_name)
+{
+ char group_ou[512];
+ char group_membership[3];
+ char *call_args[6];
+ char *av[2];
+ int rc;
+
+ member_base = NULL;
+ memset(group_ou, 0, sizeof(group_ou));
+ memset(group_membership, 0, sizeof(group_membership));
+ av[0] = group_name;
+ call_args[0] = (char *)ldap_handle;
+ call_args[1] = dn_path;
+ call_args[2] = group_name;
+ call_args[3] = group_ou;
+ call_args[4] = group_membership;
+ if (rc = mr_query("get_list_info", 1, av, get_group_info, call_args))
+ {
+ critical_alert("AD incremental",
+ "Moira error retrieving information from list %s: %s",
+ group_name, error_message(rc));
+ return(rc);
+ }
+
+ if (rc = mr_query("get_members_of_list", 1, av, member_list_build,
+ call_args))
+ {
+ critical_alert("AD incremental",
+ "Moira error retrieving list members from list %s: %s",
+ group_name, error_message(rc));
+ goto cleanup;
+ }
+ if (rc = member_list_process(ldap_handle, dn_path, group_name, call_args[3],
+ call_args[4]))
+ {
+ if ((rc != 0) && (rc != 1))
+ {
+ critical_alert("AD incremental",
+ "LDAP error updating AD membership list for list %s: %d",
+ group_name, rc);
+ }
+ goto cleanup;
+ }
+cleanup:
+ linklist_free(member_base);
+ return(rc);
+}
+
+int user_change_status(LDAP *ldap_handle, char *dn_path, char *u_name,
+ int operation)
+{
+ char filter_exp[1024];
+ char *attr_array[3];
+ char temp[256];
+ char distinguished_name[1024];
+ char user_name[512];
+ char **modvalues;
+ LDAPMod *mods[20];
+ LK_ENTRY *group_base;
+ int group_count;
+ int rc;
+ int i;
+ int n;
+ ULONG ulongValue;
+
+ if (!check_string(u_name))
+ return(0);
+ strcpy(user_name, u_name);
+ group_count = 0;
+ group_base = NULL;
+ sprintf(filter_exp, "(sAMAccountName=%s)", user_name);
+ attr_array[0] = "UserAccountControl";
+ attr_array[1] = NULL;
+ if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array,
+ &group_base, &group_count)) != 0)
+ {
+ critical_alert("AD incremental",
+ "LDAP server couldn't process user %s: %s",
+ user_name, "no memory");
+ goto cleanup;
+ }
+
+ if (group_count == 0)
+ {
+ critical_alert("AD incremental",
+ "LDAP server couldn't process user %s: %s",
+ user_name, "user not found in AD");
+ goto cleanup;
+ }
+
+ strcpy(distinguished_name, group_base->dn);
+ ulongValue = atoi((*group_base).value);
+ if (operation == MEMBER_DEACTIVATE)
+ ulongValue |= UF_ACCOUNTDISABLE;
+ else
+ ulongValue &= ~UF_ACCOUNTDISABLE;
+ sprintf(temp, "%ld", ulongValue);
+ if ((rc = construct_newvalues(group_base, group_count, (*group_base).value,
+ temp, &modvalues, REPLACE)) == 1)
+ goto cleanup;
+ linklist_free(group_base);
+ group_base = NULL;
+ group_count = 0;
+ n = 0;
+ ADD_ATTR("UserAccountControl", modvalues, LDAP_MOD_REPLACE);
+ mods[n] = NULL;
+ rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
+ for (i = 0; i < n; i++)
+ free(mods[i]);
+ free_values(modvalues);
+ if (rc != LDAP_SUCCESS)
+ {
+ critical_alert("AD incremental",
+ "LDAP server couldn't process user %s: %d",
+ user_name, rc);
+ }
+cleanup:
+ linklist_free(group_base);
+ return(rc);
+}
+
+int user_delete(LDAP *ldap_handle, char *dn_path, char *u_name)
+{
+ char filter_exp[1024];
+ char *attr_array[3];
+ char distinguished_name[1024];
+ char user_name[512];
+ LK_ENTRY *group_base;
+ int group_count;
+ int rc;
+
+ if (!check_string(u_name))
+ return(0);
+ strcpy(user_name, u_name);
+ group_count = 0;
+ group_base = NULL;
+ sprintf(filter_exp, "(sAMAccountName=%s)", user_name);
+ attr_array[0] = "name";
+ attr_array[1] = NULL;
+ if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array,
+ &group_base, &group_count)) != 0)
+ {
+ critical_alert("AD incremental",
+ "LDAP server couldn't process user %s: %s",
+ user_name, "no memory");
+ goto cleanup;
+ }
+
+ if (group_count == 0)
+ {
+ critical_alert("AD incremental",
+ "LDAP server couldn't process user %s: %s",
+ user_name, "user not found in AD");
+ goto cleanup;
+ }
+
+ strcpy(distinguished_name, group_base->dn);
+ if (rc = ldap_delete_s(ldap_handle, distinguished_name))
+ {
+ critical_alert("AD incremental",
+ "LDAP server couldn't process user %s: %s",
+ user_name, "cannot delete user from AD");
+ }
+
+cleanup:
+ linklist_free(group_base);
+ return(rc);
+}
+
+void linklist_free(LK_ENTRY *linklist_base)
+{
+ LK_ENTRY *linklist_previous;
+
+ while (linklist_base != NULL)
+ {
+ if (linklist_base->dn != NULL)
+ free(linklist_base->dn);
+ if (linklist_base->attribute != NULL)
+ free(linklist_base->attribute);
+ if (linklist_base->value != NULL)
+ free(linklist_base->value);
+ if (linklist_base->member != NULL)
+ free(linklist_base->member);
+ if (linklist_base->type != NULL)
+ free(linklist_base->type);
+ if (linklist_base->list != NULL)
+ free(linklist_base->list);
+ linklist_previous = linklist_base;
+ linklist_base = linklist_previous->next;
+ free(linklist_previous);
+ }
+}
+
+void free_values(char **modvalues)
+{
+ int i;
+
+ i = 0;
+ if (modvalues != NULL)
+ {
+ while (modvalues[i] != NULL)
+ {
+ free(modvalues[i]);
+ modvalues[i] = NULL;
+ ++i;
+ }
+ free(modvalues);
+ }
+}
+
+int sid_update(LDAP *ldap_handle, char *dn_path)
+{
+ LK_ENTRY *ptr;
+ int rc;
+ unsigned char temp[126];
+ char *av[3];
+
+ ptr = sid_base;
+
+ while (ptr != NULL)
+ {
+ memset(temp, 0, sizeof(temp));
+ convert_b_to_a(temp, ptr->value, ptr->length);
+ av[0] = ptr->member;
+ av[1] = temp;
+ if (ptr->type == (char *)GROUPS)
+ {
+ ptr->type = NULL;
+ rc = mr_query("add_list_sid_by_name", 2, av, NULL, NULL);
+ }
+ else if (ptr->type == (char *)USERS)
+ {
+ ptr->type = NULL;
+ rc = mr_query("add_user_sid_by_login", 2, av, NULL, NULL);
+ }
+ ptr = ptr->next;
+ }
+ return(0);
+}
+
+void convert_b_to_a(char *string, UCHAR *binary, int length)
+{
+ int i;
+ int j;
+ UCHAR tmp;
+
+ j = 0;
+ for (i = 0; i < length; i++)
+ {
+ tmp = binary[i];
+ string[j] = tmp;
+ string[j] >>= 4;
+ string[j] &= 0x0f;
+ string[j] += 0x30;
+ if (string[j] > '9')
+ string[j] += 0x27;
+ ++j;
+ string[j] = tmp & 0x0f;
+ string[j] += 0x30;
+ if (string[j] > '9')
+ string[j] += 0x27;
+ j++;
+ }
+ string[j] = 0;
+}
+
+static int illegalchars[] = {
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^@ - ^O */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^P - ^_ */
+ 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, /* SPACE - / */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, /* 0 - ? */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* @ - O */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, /* P - _ */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ` - o */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, /* p - ^? */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+};
+
+int check_string(char *s)
+{
+ for (; *s; s++)
+ {
+ if (isupper(*s))
+ *s = tolower(*s);
+ if (illegalchars[(unsigned) *s])
+ return 0;
+ }
+ return 1;
+}
+
+int mr_connect_cl(char *server, char *client, int version, int auth)
+{
+ int status;
+ char *motd;
+
+ status = mr_connect(server);
+ if (status)
+ {
+ com_err(whoami, status, "while connecting to Moira");
+ return MRCL_FAIL;
+ }
+
+ status = mr_motd(&motd);
+ if (status)
+ {
+ mr_disconnect();
+ com_err(whoami, status, "while checking server status");
+ return MRCL_FAIL;
+ }
+ if (motd)
+ {
+ fprintf(stderr, "The Moira server is currently unavailable:\n%s\n",
+ motd);
+ mr_disconnect();
+ return MRCL_FAIL;
+ }
+
+ status = mr_version(version);
+ if (status)
+ {
+ if (status == MR_UNKNOWN_PROC)
+ {
+ if (version > 2)
+ status = MR_VERSION_HIGH;
+ else
+ status = MR_SUCCESS;
+ }
+
+ if (status == MR_VERSION_HIGH)
+ {
+ com_err(whoami, 0, "Warning: This client is running newer code than the server.");
+ com_err(whoami, 0, "Some operations may not work.");
+ }
+ else if (status && status != MR_VERSION_LOW)
+ {
+ com_err(whoami, status, "while setting query version number.");
+ mr_disconnect();
+ return MRCL_FAIL;
+ }
+ }
+
+ if (auth)
+ {
+ status = mr_auth(client);
+ if (status)
+ {
+ com_err(whoami, status, "while authenticating to Moira.");
+ mr_disconnect();
+ return MRCL_AUTH_ERROR;
+ }
+ }
+
+ return MRCL_SUCCESS;
+}
+