Module Name:
- ksetpw.c
+ setpw.c
Abstract:
*
*/
+
#define NEED_SOCKETS
#include <krb5.h>
#include <krb.h>
+#include <ldap.h>
#ifdef _WIN32
+#include <wshelper.h>
#include "k5-int.h"
#include "adm_err.h"
#include "krb5_err.h"
-#endif
-#include <auth_con.h>
-#include "kpasswd.h"
-
-#ifndef _WIN32
+#else
#include <sys/socket.h>
#include <netdb.h>
#include <sys/select.h>
#endif
-
+#include <auth_con.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/timeb.h>
#include <errno.h>
+#include "kpasswd.h"
+#include "gsssasl.h"
+#include "gssldap.h"
#define PW_LENGTH 25
+#define KDC_PORT 464
+#define ULONG unsigned long
#ifndef krb5_is_krb_error
#define krb5_is_krb_error(dat)\
- ((dat) && (dat)->length && ((dat)->data[0] == 0x7e ||\
- (dat)->data[0] == 0x5e))
+ ((dat) && (dat)->length && ((dat)->data[0] == 0x7e ||\
+ (dat)->data[0] == 0x5e))
+#endif
+
+#ifdef _WIN32
+#define sleep(Seconds) Sleep(Seconds * 1000)
+#define gethostbyname(Server) rgethostbyname(Server)
#endif
/* Win32 defines. */
/*
* This MUST be equal to the sum of all elements in the above array.
*/
+
+struct sockaddr_in kdc_server;
+SOCKET kdc_socket;
+krb5_context context;
+krb5_ccache ccache;
+krb5_auth_context auth_context = NULL;
+krb5_data ap_req;
+krb5_creds *credsp = NULL;
+krb5_creds creds;
+char connected_server[128];
+
static int total_sum = 11646;
+int get_krb5_error(krb5_error_code rc, char *in, char *out);
+int ad_connect(LDAP **ldap_handle, char *ldap_domain, char *dn_path,
+ char *Win2kPassword, char *Win2kUser, char *default_server,
+ int connect_to_kdc);
+int ad_kdc_connect(char *connectedServer);
+int ad_server_connect(char *connectedServer, char *domain);
+void ad_kdc_disconnect();
+int compare_elements(const void *arg1, const void *arg2);
+int convert_domain_to_dn(char *domain, char *dnp);
+int set_password(char *user, char *password, char *domain);
+
+int locate_ldap_server(char *domain, char **server_name);
+
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);
+ PROTOTYPE((const krb5_setpw *rep, krb5_data ** code));
-krb5_error_code krb5_mk_setpw_req(krb5_context context, krb5_auth_context auth_context,
+krb5_error_code make_setpw_req(krb5_context context, krb5_auth_context auth_context,
krb5_data *ap_req, krb5_principal targprinc,
char *passwd, krb5_data *packet)
{
char *ptr;
register int count = 2;
- memset (&setpw, 0, sizeof(krb5_setpw));
+ memset(&setpw, 0, sizeof(krb5_setpw));
if (ret = krb5_auth_con_setflags(context, auth_context,
KRB5_AUTH_CONTEXT_DO_SEQUENCE))
return(ret);
ptr += ap_req->length;
/* krb-priv of password */
memcpy(ptr, cipherpw.data, cipherpw.length);
+ free(cipherpw.data);
+/* krb5_free_data_contents(context, &cipherpw);*/
+ krb5_free_data(context, encoded_setpw);
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)
+krb5_error_code get_setpw_rep(krb5_context context, krb5_auth_context auth_context,
+ krb5_data *packet, int *result_code,
+ krb5_data *result_data)
{
char *ptr;
int plen;
{
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)
if ((ap_rep.length == 0) && (*result_code == KRB5_KPASSWD_SUCCESS))
{
ret = KRB5KRB_AP_ERR_MODIFIED;
- goto cleanup;
+ goto cleanup;
}
result_data->length = (clearresult.data + clearresult.length) - ptr;
if (result_data->length)
memcpy(result_data->data, ptr, result_data->length);
}
else
- result_data->data = NULL;
+ result_data->data = NULL;
ret = 0;
cleanup:
if (ap_rep.length)
free(clearresult.data);
else
- krb5_free_error(context, krberror);
+ krb5_free_error(context, krberror);
return(ret);
}
-krb5_error_code krb5_set_password(krb5_context context, krb5_ccache ccache,
+krb5_error_code kdc_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 chpw_snd;
+ krb5_data chpw_rcv;
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;
+ int nfds;
krb5_principal targprinc;
- int count;
- int last_count;
+ 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(&chpw_snd, 0, sizeof(krb5_data));
+ memset(&chpw_rcv, 0, sizeof(krb5_data));
memset(userrealm, '\0', sizeof(userrealm));
targprinc = NULL;
+
+ chpw_rcv.length = 1500;
+ chpw_rcv.data = (char *) calloc(1, chpw_rcv.length);
+
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;
+ if (credsp == NULL)
+ {
+ memset(&creds, 0, sizeof(creds));
+ memset(&ap_req, 0, sizeof(krb5_data));
+ 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 ((s1 = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET)
+ addrlen = sizeof(local_addr);
+ if (getsockname(kdc_socket, &local_addr, &addrlen) < 0)
{
- free(addr_p);
- return(errno);
+ code = KDC_GETSOCKNAME_ERROR;
+ goto cleanup;
}
- if ((s2 = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET)
+ if (((struct sockaddr_in *)&local_addr)->sin_addr.s_addr != 0)
{
- closesocket(s1);
- free(addr_p);
- return(errno);
+ 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);
}
- error_count = 0;
- for (i=0; i<out; i++)
+ else
{
- 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)
- {
-printf("1\n");
- 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);
+ 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);
+ }
- 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;
+ addrlen = sizeof(remote_addr);
+ if (getpeername(kdc_socket, &remote_addr, &addrlen) < 0)
+ {
+ code = KDC_GETPEERNAME_ERROR;
+ goto cleanup;
+ }
+ 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);
- if ((cc = sendto(s1, chpw_req.data, chpw_req.length, 0,
- (struct sockaddr *) &addr_p[i],
- sizeof(addr_p[i]))) != chpw_req.length)
- continue;
+ if (code = krb5_auth_con_setaddrs(context, auth_context, &local_kaddr, NULL))
+ goto cleanup;
+ if (code = make_setpw_req(context, auth_context, &ap_req,
+ targprinc, newpw, &chpw_snd))
+ goto cleanup;
- if (chpw_req.data != NULL)
- free(chpw_req.data);
- chpw_rep.length = 1500;
- chpw_rep.data = (char *) calloc(1, chpw_rep.length);
+ for (i = 0; i < 3; i++)
+ {
+ if ((cc = sendto(kdc_socket, chpw_snd.data, chpw_snd.length, 0,
+ NULL,
+ 0)) != chpw_snd.length)
+ {
+ code = KDC_SEND_ERROR;
+ sleep(1);
+ continue;
+ }
- tmp_len = sizeof(tmp_addr);
- last_count = 0;
- while (1)
+ TimeVal.tv_sec = 3;
+ TimeVal.tv_usec = 0;
+ FD_ZERO(&readfds);
+ FD_SET(kdc_socket, &readfds);
+ nfds = kdc_socket + 1;
+ code = select(nfds, &readfds, NULL, NULL, &TimeVal);
+ if ((code == 0) || (code == SOCKET_ERROR))
{
- cc = recvfrom(s1, chpw_rep.data, chpw_rep.length, MSG_PEEK,
- &tmp_addr, &tmp_len);
- if ((last_count == cc) && (cc != 0))
- break;
- last_count = cc;
- if (cc == 0)
- {
- if (last_count == -1)
- break;
- last_count = -1;
- }
+ code = KDC_RECEIVE_TIMEOUT;
sleep(1);
+ continue;
}
- if ((cc = recvfrom(s1, chpw_rep.data, chpw_rep.length, 0, &tmp_addr, &tmp_len)) < 0)
+
+ if ((cc = recvfrom(kdc_socket, chpw_rcv.data, chpw_rcv.length, 0,
+ NULL, NULL)) < 0)
{
- code = errno;
- goto cleanup;
+ code = KDC_RECEIVE_TIMEOUT;
+ sleep(1);
+ continue;
}
- chpw_rep.length = cc;
- if (code = krb5_auth_con_setaddrs(context, auth_context, NULL,
- &remote_kaddr))
+ chpw_rcv.length = cc;
+ if (code = krb5_auth_con_setaddrs(context, auth_context, NULL, &remote_kaddr))
{
- goto cleanup;
+ sleep(1);
+ continue;
}
local_result_code = 0;
- code = krb5_rd_setpw_rep(context, auth_context, &chpw_rep,
- &local_result_code, &result_string);
+ code = get_setpw_rep(context, auth_context, &chpw_rcv,
+ &local_result_code, &result_string);
if (local_result_code)
{
local_result_code = KRB5_KPASSWD_SUCCESS;
*result_code = local_result_code;
}
- if (chpw_rep.data != NULL)
- free(chpw_rep.data);
- break;
-
+ if ((code == 0) && (local_result_code == 0))
+ break;
+ sleep(1);
}
+
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)
- free(ap_req.data);
- krb5_free_cred_contents(context, &creds);
- if (credsp != NULL)
- krb5_free_creds(context, credsp);
+ if (chpw_snd.data != NULL)
+ free(chpw_snd.data);
+ if (chpw_rcv.data != NULL)
+ free(chpw_rcv.data);
if (targprinc != NULL)
krb5_free_principal(context, targprinc);
return(code);
}
-int set_password(char *user, char *domain)
+int set_password(char *user, char *password, 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);
+ if (strlen(password) != 0)
+ strcpy(pw, password);
+ else
+ generate_password(pw);
res_code = 0;
- retval = krb5_set_password(context, ccache, pw, user, domain, &res_code);
+ retval = kdc_set_password(context, ccache, pw, user, domain, &res_code);
- krb5_cc_close(context, ccache);
- krb5_free_context(context);
- if (retval)
- return(retval);
- return(res_code);
+ if (res_code)
+ return(res_code);
+ return(retval);
}
void generate_password(char *password)
}
return (rand());
}
+
+int get_krb5_error(krb5_error_code rc, char *in, char *out)
+{
+ int krb5Error;
+ int retval;
+
+ retval = 1;
+
+ if (rc < 0)
+ {
+ krb5Error = ((int)(rc & 255));
+ sprintf(out, "%s: %s(%ld)", in, error_message(rc), krb5Error);
+ }
+ else
+ {
+ switch (rc)
+ {
+ case KDC_RECEIVE_TIMEOUT:
+ {
+ retval = 0;
+ sprintf(out, "%s: %s(%d)", in, "Receive timeout", rc);
+ break;
+ }
+ case KDC_RECEIVE_ERROR:
+ {
+ retval = 0;
+ sprintf(out, "%s: %s(%d)", in, "Receive error", rc);
+ break;
+ }
+ case KRB5_KPASSWD_MALFORMED:
+ {
+ sprintf(out, "%s: %s(%d)", in, "malformed password", rc);
+ break;
+ }
+ case KRB5_KPASSWD_HARDERROR:
+ {
+ sprintf(out, "%s: %s(%d)", in, "hard error", rc);
+ break;
+ }
+ case KRB5_KPASSWD_AUTHERROR:
+ {
+ retval = 0;
+ sprintf(out, "%s: %s(%d)", in, "authentication error", rc);
+ break;
+ }
+ case KRB5_KPASSWD_SOFTERROR:
+ {
+ retval = 0;
+ sprintf(out, "%s: %s(%d)", in, "soft error", rc);
+ break;
+ }
+ case KRB5_KPASSWD_ACCESSDENIED:
+ {
+ sprintf(out, "%s: %s(%d)", in, "Access denied", rc);
+ break;
+ }
+ case KDC_SEND_ERROR:
+ {
+ retval = 0;
+ sprintf(out, "%s: %s(%d)", in, "Send error", rc);
+ break;
+ }
+ case KDC_GETSOCKNAME_ERROR:
+ {
+ retval = 0;
+ sprintf(out, "%s: %s(%d)", in, "Socket error - getsockname", rc);
+ break;
+ }
+ case KDC_GETPEERNAME_ERROR:
+ {
+ retval = 0;
+ sprintf(out, "%s: %s(%d)", in, "Socket error - getpeername", rc);
+ break;
+ }
+ default:
+ {
+ sprintf(out, "%s: %s(%d)", in, "unknown error", rc);
+ break;
+ }
+ }
+ }
+ return(retval);
+}
+
+int ad_connect(LDAP **ldap_handle, char *ldap_domain, char *dn_path,
+ char *Win2kPassword, char *Win2kUser, char *default_server,
+ int connect_to_kdc)
+{
+ int i;
+ int j;
+ char *server_name[MAX_SERVER_NAMES];
+ char server_array[MAX_SERVER_NAMES][256];
+ static char temp[128];
+ ULONG version = LDAP_VERSION3;
+ ULONG rc;
+ int Max_wait_time = 500;
+ int Max_size_limit = LDAP_NO_LIMIT;
+
+ if (ldap_domain == NULL)
+ ldap_domain = "win.mit.edu";
+ convert_domain_to_dn(ldap_domain, dn_path);
+ if (strlen(dn_path) == 0)
+ return(1);
+
+ memset(server_name, 0, sizeof(server_name[0]) * MAX_SERVER_NAMES);
+ memset(server_array, 0, sizeof(server_array[0]) * MAX_SERVER_NAMES);
+ if (strlen(default_server) == 0)
+ {
+ if (locate_ldap_server(ldap_domain, server_name) == -1)
+ return(2);
+ j = 0;
+ for (i = 0; i < MAX_SERVER_NAMES; i++)
+ {
+ if (server_name[i] != NULL)
+ {
+ strcpy(server_array[i], server_name[i]);
+ free(server_name[i]);
+ j++;
+ }
+ }
+ if (j == 0)
+ return(2);
+#ifdef _WIN32
+ qsort((void *)server_array, (size_t)j, sizeof(server_array[0]), compare_elements);
+#endif
+ }
+ else
+ strcpy(server_array[0], default_server);
+
+ for (i = 0; i < MAX_SERVER_NAMES; i++)
+ {
+ if (strlen(server_array[i]) != 0)
+ {
+ if (((*ldap_handle) = ldap_open(server_array[i], LDAP_PORT)) != NULL)
+ {
+ rc = ldap_set_option((*ldap_handle), LDAP_OPT_PROTOCOL_VERSION, &version);
+ rc = ldap_set_option((*ldap_handle), LDAP_OPT_TIMELIMIT,
+ (void *)&Max_wait_time);
+ rc = ldap_set_option((*ldap_handle), LDAP_OPT_SIZELIMIT,
+ (void *)&Max_size_limit);
+ rc = ldap_set_option((*ldap_handle), LDAP_OPT_REFERRALS, LDAP_OPT_OFF);
+ rc = ldap_adgssapi_bind((*ldap_handle), dn_path, GSSSASL_PRIVACY_PROTECTION);
+ if (rc == LDAP_SUCCESS)
+ {
+ if (connect_to_kdc)
+ {
+ if (!ad_server_connect(server_array[i], ldap_domain))
+ {
+ ldap_unbind_s((*ldap_handle));
+ continue;
+ }
+ }
+ if (strlen(default_server) == 0)
+ strcpy(default_server, server_array[i]);
+ strcpy(connected_server, server_array[i]);
+ break;
+ }
+ }
+ }
+ }
+ if (i >= MAX_SERVER_NAMES)
+ return(3);
+ return(0);
+}
+
+int ad_server_connect(char *connectedServer, char *domain)
+{
+ krb5_error_code rc;
+ krb5_creds creds;
+ krb5_creds *credsp;
+ char temp[256];
+ char userrealm[256];
+ int i;
+ unsigned short port = KDC_PORT;
+
+ context = NULL;
+ credsp = NULL;
+ memset(&ccache, 0, sizeof(ccache));
+ memset(&creds, 0, sizeof(creds));
+ memset(userrealm, '\0', sizeof(userrealm));
+
+ rc = 0;
+ if (krb5_init_context(&context))
+ goto cleanup;
+ if (krb5_cc_default(context, &ccache))
+ goto cleanup;
+
+ for (i = 0; i < (int)strlen(domain); i++)
+ userrealm[i] = toupper(domain[i]);
+ sprintf(temp, "%s@%s", "kadmin/changepw", userrealm);
+ if (krb5_parse_name(context, temp, &creds.server))
+ goto cleanup;
+ if (krb5_cc_get_principal(context, ccache, &creds.client))
+ goto cleanup;
+ if (krb5_get_credentials(context, 0, ccache, &creds, &credsp))
+ goto cleanup;
+
+ rc = ad_kdc_connect(connectedServer);
+
+
+cleanup:
+ if (!rc)
+ {
+ krb5_cc_close(context, ccache);
+ krb5_free_context(context);
+ }
+ krb5_free_cred_contents(context, &creds);
+ if (credsp != NULL)
+ krb5_free_creds(context, credsp);
+ return(rc);
+}
+
+
+int ad_kdc_connect(char *connectedServer)
+{
+ struct hostent *hp;
+ int rc;
+
+ rc = 0;
+ hp = gethostbyname(connectedServer);
+ if (hp == NULL)
+ goto cleanup;
+ memset(&kdc_server, 0, sizeof(kdc_server));
+ memcpy(&(kdc_server.sin_addr),hp->h_addr_list[0],hp->h_length);
+ kdc_server.sin_family = hp->h_addrtype;
+ kdc_server.sin_port = htons(KDC_PORT);
+
+ if ((kdc_socket = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET)
+ goto cleanup;
+ if (connect(kdc_socket, (struct sockaddr*)&kdc_server, sizeof(kdc_server)) == SOCKET_ERROR)
+ goto cleanup;
+ rc = 1;
+
+cleanup:
+ return(rc);
+}
+
+void ad_kdc_disconnect()
+{
+
+ if (auth_context != NULL)
+ {
+ krb5_auth_con_free(context, auth_context);
+ if (ap_req.data != NULL)
+ free(ap_req.data);
+ krb5_free_cred_contents(context, &creds);
+ if (credsp != NULL)
+ krb5_free_creds(context, credsp);
+ }
+ credsp = NULL;
+ auth_context = NULL;
+ if (context != NULL)
+ {
+ krb5_cc_close(context, ccache);
+ krb5_free_context(context);
+ }
+ closesocket(kdc_socket);
+
+}
+
+int convert_domain_to_dn(char *domain, char *dnp)
+{
+ char *fp;
+ char *dp;
+ char dn[512];
+
+ memset(dn, '\0', sizeof(dn));
+ strcpy(dn, "dc=");
+ dp = dn+3;
+ for (fp = domain; *fp; fp++)
+ {
+ if (*fp == '.')
+ {
+ strcpy(dp, ",dc=");
+ dp += 4;
+ }
+ else
+ *dp++ = *fp;
+ }
+
+ strcpy(dnp, dn);
+ return 0;
+}
+
+int compare_elements(const void *arg1, const void *arg2)
+{
+ int rc;
+
+ rc = strcmp((char*)arg1, (char*)arg2);
+ if (rc < 0)
+ return(1);
+ if (rc > 0)
+ return(-1);
+ return(rc);
+}
+
#include <malloc.h>
#include <lmaccess.h>
#endif
-
+#include <hesiod.h>
#include <string.h>
#include <ldap.h>
#include <stdio.h>
#endif /* _WIN32 */
#ifndef _WIN32
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
#include <sys/utsname.h>
#include <unistd.h>
+#define strnicmp(A,B,C) strncasecmp(A,B,C)
#define UCHAR unsigned char
#define UF_SCRIPT 0x0001
} SID;
#endif/*!WIN32*/
+#define AFS "/afs/"
+#define WINAFS "\\\\afs\\all\\"
+
#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 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 MEMBER_DEACTIVATE 5
#define MEMBER_CREATE 6
+#define MOIRA_ALL 0x0
+#define MOIRA_USERS 0x1
+#define MOIRA_KERBEROS 0x2
+#define MOIRA_STRINGS 0x4
+#define MOIRA_LISTS 0x8
+
+#define ADFS_ADD 1
+#define ADFS_DELETE 2
+
typedef struct lk_entry {
int op;
int length;
LK_ENTRY *sid_base = NULL;
LK_ENTRY **sid_ptr = NULL;
static char tbl_buf[1024];
-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 kerberos_ou[] = "OU=kerberos, OU=moira";
+char contact_ou[] = "OU=strings, OU=moira";
+char user_ou[] = "OU=users, OU=moira";
+char group_ou_distribution[] = "OU=mail, OU=lists, OU=moira";
+char group_ou_root[] = "OU=lists, OU=moira";
+char group_ou_security[] = "OU=group, OU=lists, OU=moira";
+char group_ou_neither[] = "OU=special, OU=lists, OU=moira";
+char group_ou_both[] = "OU=mail, OU=group, OU=lists, OU=moira";
char *whoami;
char group_manager[64];
char ldap_domain[256];
int group_flag;
int mr_connections = 0;
int callback_rc;
+char default_server[256];
-extern int locate_ldap_server(char *domain, char *server_name[]);
-extern int set_password(char *user, char *domain);
+extern int set_password(char *user, char *password, char *domain);
+void AfsToWinAfs(char* path, char* winPath);
+int ad_connect(LDAP **ldap_handle, char *ldap_domain, char *dn_path,
+ char *Win2kPassword, char *Win2kUser, char *default_server,
+ int connect_to_kdc);
+void ad_kdc_disconnect();
void check_winad(void);
+void expand_groups(LDAP *ldap_handle, char *dn_path, char *group_name);
+int filesys_process(int ac, char **av, void *ptr);
int user_create(int ac, char **av, void *ptr);
int user_change_status(int ac, char **av, void *ptr);
int user_delete(LDAP *ldap_handle, char *dn_path, char *u_name);
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_rename(int ac, char **av, void *ptr);
+int list_list_build(int ac, char **av, void *ptr);
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, char *group_gid);
+ char *group_ou, char *group_membership, char *group_gid,
+ int operation);
int member_remove(LDAP *ldap_handle, char *dn_path, char *group_name,
char *group_ou, char *group_membership, char *group_gid);
int sid_update(LDAP *ldap_handle, char *dn_path);
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,
+void do_filesys(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);
+void do_user(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
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);
void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
char **before, int beforec, char **after, int afterc);
int linklist_create_entry(char *attribute, char *value,
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;
+ char dn_path[256];
whoami = ((whoami = (char *)strrchr(argv[0], '/')) ? whoami+1 : argv[0]);
for (i = 0; i < beforec; i++)
{
if (i > 0)
- strcat(tbl_buf, ",");
+ strcat(tbl_buf, ",");
strcat(tbl_buf, before[i]);
}
strcat(tbl_buf, ")->(");
for (i = 0; i < afterc; i++)
{
if (i > 0)
- strcat(tbl_buf, ",");
+ strcat(tbl_buf, ",");
strcat(tbl_buf, after[i]);
}
strcat(tbl_buf, ")");
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_domain, &dn_path);
- if (dn_path == NULL)
- {
- 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)
+ memset(default_server, '\0', sizeof(default_server));
+ memset(dn_path, '\0', sizeof(dn_path));
+ if (ad_connect(&ldap_handle, ldap_domain, dn_path, "", "", default_server, 1))
{
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_PRIVACY_PROTECTION);
- if (rc != LDAP_SUCCESS)
- exit(1);
for (i = 0; i < (int)strlen(table); i++)
table[i] = tolower(table[i]);
if (!strcmp(table, "users"))
- do_user(ldap_handle, ldap_entry, ldap_domain, dn_path, before, beforec,
- after, afterc);
+ do_user(ldap_handle, dn_path, ldap_domain, before, beforec, after,
+ afterc);
else if (!strcmp(table, "list"))
do_list(ldap_handle, dn_path, ldap_domain, before, beforec, after,
afterc);
else if (!strcmp(table, "imembers"))
do_member(ldap_handle, dn_path, ldap_domain, before, beforec, after,
afterc);
-/*
else if (!strcmp(table, "filesys"))
- do_filesys(before, beforec, after, afterc);
+ do_filesys(ldap_handle, dn_path, ldap_domain, before, beforec, after,
+ afterc);
+/*
else if (!strcmp(table, "quota"))
do_quota(before, beforec, after, afterc);
*/
+
+ ad_kdc_disconnect();
rc = ldap_unbind_s(ldap_handle);
- free(dn_path);
exit(0);
}
+void do_filesys(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
+ char **before, int beforec, char **after, int afterc)
+{
+ long rc;
+ char *av[3];
+ char *call_args[7];
+ int acreate;
+ int atype;
+ int bcreate;
+ int btype;
+
+ if (rc = moira_connect())
+ {
+ critical_alert("AD incremental",
+ "Error contacting Moira server : %s",
+ error_message(rc));
+ return;
+ }
+
+ if (afterc < FS_CREATE)
+ atype = acreate = 0;
+ else
+ {
+ atype = !strcmp(after[FS_TYPE], "AFS");
+ acreate = atoi(after[FS_CREATE]);
+ }
+
+ if (beforec < FS_CREATE)
+ {
+ if (acreate == 0 || atype == 0)
+ goto cleanup;
+ com_err(whoami, 0, "Processing filesys %s", after[FS_NAME]);
+ av[0] = after[FS_NAME];
+ call_args[0] = (char *)ldap_handle;
+ call_args[1] = dn_path;
+ call_args[2] = after[FS_NAME];
+ call_args[3] = (char *)ADFS_ADD;
+ if (rc = mr_query("get_filesys_by_label", 1, av, filesys_process, call_args))
+ {
+ critical_alert("AD incremental", "Couldn't process filesys %s : %s",
+ after[FS_NAME], error_message(rc));
+ goto cleanup;
+ }
+ goto cleanup;
+ }
+
+ btype = !strcmp(before[FS_TYPE], "AFS");
+ bcreate = atoi(before[FS_CREATE]);
+ if (afterc < FS_CREATE)
+ {
+ if (btype && bcreate)
+ {
+ av[0] = before[FS_NAME];
+ av[1] = before[FS_TYPE];
+ call_args[0] = (char *)ldap_handle;
+ call_args[1] = dn_path;
+ call_args[2] = before[FS_NAME];
+ call_args[3] = (char *)ADFS_DELETE;
+ if (filesys_process(beforec, before, (void *)call_args))
+ {
+ critical_alert("AD incremental", "Couldn't delete filesys %s : %s",
+ before[FS_NAME], error_message(rc));
+ }
+ }
+ goto cleanup;
+ }
+
+ if (!acreate)
+ goto cleanup;
+
+ if (!atype && !btype)
+ {
+ if (strcmp(before[FS_TYPE], "ERR") || strcmp(after[FS_TYPE], "ERR"))
+ {
+ critical_alert("incremental", "Filesystem %s or %s is not AFS: "
+ "Operation not supported", before[FS_NAME], after[FS_NAME]);
+ goto cleanup;
+ }
+ }
+ com_err(whoami, 0, "Processing filesys %s", after[FS_NAME]);
+ av[0] = after[FS_NAME];
+ call_args[0] = (char *)ldap_handle;
+ call_args[1] = dn_path;
+ call_args[2] = after[FS_NAME];
+ call_args[3] = (char *)ADFS_ADD;
+ if (rc = mr_query("get_filesys_by_label", 1, av, filesys_process, call_args))
+ {
+ critical_alert("AD incremental", "Couldn't process filesys %s : %s",
+ after[FS_NAME], error_message(rc));
+ goto cleanup;
+ }
+cleanup:
+ moira_disconnect();
+ return;
+}
void do_list(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
char **before, int beforec, char **after, int afterc)
{
int astatus;
long rc;
char *av[3];
- char *call_args[6];
-
+ char *call_args[7];
if (beforec == 0 && afterc == 0)
return;
call_args[3] = NULL;
call_args[4] = NULL;
call_args[5] = NULL;
+ call_args[6] = (char *)(MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS);
sid_base = NULL;
sid_ptr = &sid_base;
if (rc = mr_query("get_list_info", 1, av, group_create, call_args))
{
sid_update(ldap_handle, dn_path);
linklist_free(sid_base);
+ sid_base = NULL;
}
if (afterc == 0)
goto cleanup;
member_base = NULL;
- if (!(rc = mr_query("get_members_of_list", 1, av, member_list_build,
+ if (!(rc = mr_query("get_end_members_of_list", 1, av, member_list_build,
call_args)))
{
if (member_base != NULL)
- rc = member_list_process(ldap_handle, dn_path, after[L_NAME],
- call_args[3], call_args[4], call_args[5]);
+ {
+ rc = member_list_process(ldap_handle, dn_path, after[L_NAME],
+ call_args[3], call_args[4], call_args[5],
+ MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS);
+ expand_groups(ldap_handle, dn_path, after[L_NAME]);
+ }
}
else
{
after[L_NAME], error_message(rc));
}
linklist_free(member_base);
+ member_base = NULL;
goto cleanup;
}
cleanup:
moira_disconnect();
}
-#define LM_EXTRA_ACTIVE (LM_END)
+#define LM_EXTRA_ACTIVE (LM_END)
void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
char **before, int beforec, char **after, int afterc)
{
- char *call_args[6];
+ char *call_args[7];
char *av[2];
char group_name[128];
char user_name[128];
user_name, error_message(rc));
return;
}
+ com_err(whoami, 0, "Updating list %s membership for user %s.", group_name,
+ user_name);
av[0] = group_name;
call_args[0] = (char *)ldap_handle;
call_args[1] = dn_path;
call_args[3] = NULL;
call_args[4] = NULL;
call_args[5] = NULL;
+ call_args[6] = (char *)(MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS);
member_base = NULL;
sid_base = NULL;
sid_ptr = &sid_base;
{
sid_update(ldap_handle, dn_path);
linklist_free(sid_base);
+ sid_base = NULL;
}
member_base = NULL;
- if (!(rc = mr_query("get_members_of_list", 1, av, member_list_build,
+ if (!(rc = mr_query("get_end_members_of_list", 1, av, member_list_build,
call_args)))
{
if (member_base == NULL)
else
{
rc = member_list_process(ldap_handle, dn_path, group_name,
- call_args[3], call_args[4], call_args[5]);
+ call_args[3], call_args[4], call_args[5],
+ MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS);
+ expand_groups(ldap_handle, dn_path, group_name);
}
}
}
user_name, group_name);
}
linklist_free(member_base);
+ member_base = NULL;
if (call_args[3] != NULL)
free(call_args[3]);
if (call_args[4] != NULL)
}
-void do_user(LDAP *ldap_handle, LDAPMessage *ldap_entry, char *ldap_hostname,
- char *dn_path, char **before, int beforec, char **after,
+void do_user(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
+ char **before, int beforec, char **after,
int afterc)
{
int rc;
int astate;
int bstate;
-
if ((beforec == 0) || (afterc == 0))
return;
{
if (i > 30)
{
- critical_alert("incremental",
- "WINAD incremental failed (%s exists): %s",
- STOP_FILE, tbl_buf);
- exit(1);
- }
+ critical_alert("incremental",
+ "WINAD incremental failed (%s exists): %s",
+ STOP_FILE, tbl_buf);
+ exit(1);
+ }
sleep(60);
}
}
return 0;
}
-int convert_domain_to_dn(char *domain, char **dnp)
-{
- 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;
- }
- else
- *dp++ = *fp;
- }
-
- *dnp = (char *)strdup(dn);
- return 0;
-}
-
void get_distinguished_name(LDAP *ldap_handle, LDAPMessage *ldap_entry,
char *distinguished_name)
{
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)
+ sid_ptr, &sid_count)) == LDAP_SUCCESS)
{
if (sid_count == 1)
{
strcpy(temp, av[ACE_NAME]);
if (!check_string(temp))
return(0);
- if (!strcmp(av[ACE_TYPE], "STRING"))
+ if (!strcmp(av[ACE_TYPE], "USER"))
{
- if (contact_create((LDAP *)call_args[0], call_args[1], temp, contact_ou))
- return(0);
+ if (!((int)call_args[6] & MOIRA_USERS))
+ return(0);
+ }
+ else if (!strcmp(av[ACE_TYPE], "STRING"))
+ {
+ if (!((int)call_args[6] & MOIRA_STRINGS))
+ return(0);
+ if (contact_create((LDAP *)call_args[0], call_args[1], temp, contact_ou))
+ return(0);
}
else if (!strcmp(av[ACE_TYPE], "LIST"))
{
- strcpy(temp, av[ACE_NAME]);
+ if (!((int)call_args[6] & MOIRA_LISTS))
+ return(0);
}
- else if (strcmp(av[ACE_TYPE], "USER"))
+ else if (!strcmp(av[ACE_TYPE], "KERBEROS"))
{
- if (contact_create((LDAP *)call_args[0], call_args[1], temp, kerberos_ou))
- return(0);
+ if (!((int)call_args[6] & MOIRA_KERBEROS))
+ return(0);
+ if (contact_create((LDAP *)call_args[0], call_args[1], temp, kerberos_ou))
+ return(0);
}
+ else
+ return(0);
+
linklist = member_base;
while (linklist)
{
return(0);
}
+int list_list_build(int ac, char **av, void *ptr)
+{
+ LK_ENTRY *linklist;
+ char temp[1024];
+ char **call_args;
+
+ call_args = ptr;
+
+ strcpy(temp, av[L_NAME]);
+ if (!check_string(temp))
+ return(0);
+
+ 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("LIST") + 1);
+ strcpy(linklist->type, "LIST");
+ linklist->member = calloc(1, strlen(temp) + 1);
+ strcpy(linklist->member, temp);
+ linklist->next = member_base;
+ member_base = linklist;
+ return(0);
+}
+
int member_remove(LDAP *ldap_handle, char *dn_path, char *group_name,
char *group_ou, char *group_membership, char *group_gid)
{
#define USER_COUNT 5
int member_list_process(LDAP *ldap_handle, char *dn_path, char *group_name,
- char *group_ou, char *group_membership, char *group_gid)
+ char *group_ou, char *group_membership, char *group_gid,
+ int operation)
{
char distinguished_name[1024];
char **modvalues;
}
if (!strcmp(pPtr->type, "LIST"))
{
+ if (!(operation & MOIRA_LISTS))
+ continue;
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"))
{
+ if (!(operation & MOIRA_USERS))
+ continue;
sprintf(temp, "(distinguishedName=cn=%s,%s,%s)", group_member, user_ou, dn_path);
}
else if (!strcmp(pPtr->type, "STRING"))
{
+ if (!(operation & MOIRA_STRINGS))
+ continue;
+ if ((group_membership[0] != 'B') && (group_membership[0] != 'D'))
+ continue;
sprintf(temp, "(distinguishedName=cn=%s,%s,%s)", group_member, contact_ou, dn_path);
}
else
{
+ if (!(operation & MOIRA_KERBEROS))
+ continue;
sprintf(temp, "(distinguishedName=cn=%s,%s,%s)", group_member, kerberos_ou, dn_path);
}
strcat(filter_exp, temp);
char new_dn[256];
char cn_user_name[256];
char contact_name[256];
+ char *email_v[] = {NULL, NULL};
char *cn_v[] = {NULL, NULL};
char *contact_v[] = {NULL, NULL};
char *objectClass_v[] = {"top", "person",
contact_v[0] = contact_name;
name_v[0] = user;
desc_v[0] = "Auto account created by Moira";
+ email_v[0] = user;
strcpy(new_dn, cn_user_name);
n = 0;
ADD_ATTR("name", name_v, LDAP_MOD_ADD);
ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
+ if (!strcmp(group_ou, contact_ou))
+ {
+ ADD_ATTR("mail", email_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))
+ {
+ 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))
{
critical_alert("AD incremental - contact create",
char user_name[256];
char *uid_v[] = {NULL, NULL};
char *mitid_v[] = {NULL, NULL};
+ char *homedir_v[] = {NULL, NULL};
+ char *winProfile_v[] = {NULL, NULL};
+ char *drives_v[] = {NULL, NULL};
int n;
int rc;
int i;
char **call_args;
char filter_exp[256];
char *attr_array[3];
+ char **hp;
+ char path[256];
+ char winPath[256];
+ char winProfile[256];
call_args = ptr;
mitid_v[0] = av[U_MITID];
ADD_ATTR("employeeID", mitid_v, LDAP_MOD_REPLACE);
}
+ if ((hp = hes_resolve(user_name, "filsys")) != NULL)
+ {
+ memset(path, 0, sizeof(path));
+ memset(winPath, 0, sizeof(winPath));
+ sscanf(hp[0], "%*s %s", path);
+ if (strlen(path) && strnicmp(path, AFS, strlen(AFS)) == 0)
+ {
+ AfsToWinAfs(path, winPath);
+ homedir_v[0] = winPath;
+ ADD_ATTR("homeDirectory", homedir_v, LDAP_MOD_REPLACE);
+ strcpy(winProfile, winPath);
+ strcat(winProfile, "\\.winprofile");
+ winProfile_v[0] = winProfile;
+ ADD_ATTR("profilePath", winProfile_v, LDAP_MOD_REPLACE);
+ drives_v[0] = "H:";
+ ADD_ATTR("homeDrive", drives_v, LDAP_MOD_REPLACE);
+ }
+ }
mods[n] = NULL;
if (n != 0)
{
for (i = 0; i < n; i++)
free(mods[i]);
}
+ if (hp != NULL)
+ {
+ i = 0;
+ while (hp[i])
+ {
+ free(hp[i]);
+ i++;
+ }
+ }
cleanup:
linklist_free(group_base);
return(0);
}
+int filesys_process(int ac, char **av, void *ptr)
+{
+ char distinguished_name[256];
+ char winPath[256];
+ char winProfile[256];
+ char fs_name[128];
+ char filter_exp[256];
+ char *attr_array[3];
+ char *homedir_v[] = {NULL, NULL};
+ char *winProfile_v[] = {NULL, NULL};
+ char *drives_v[] = {NULL, NULL};
+ char **call_args;
+ int group_count;
+ int n;
+ int rc;
+ int i;
+ int operation;
+ LDAPMod *mods[20];
+ LK_ENTRY *group_base;
+
+ call_args = ptr;
+
+ if (!check_string(av[FS_NAME]))
+ {
+ critical_alert("AD incremental - user filesys",
+ "invalid filesys name %s",
+ av[FS_NAME]);
+ return(0);
+ }
+
+
+ if (strcmp(av[FS_TYPE], "AFS"))
+ {
+ critical_alert("AD incremental - user filesys",
+ "invalid filesys type %s",
+ av[FS_TYPE]);
+ return(0);
+ }
+
+ strcpy(fs_name, av[FS_NAME]);
+ group_count = 0;
+ group_base = NULL;
+ sprintf(filter_exp, "(sAMAccountName=%s)", av[FS_NAME]);
+ attr_array[0] = "cn";
+ attr_array[1] = NULL;
+ if ((rc = linklist_build((LDAP *)call_args[0], call_args[1], filter_exp, attr_array,
+ &group_base, &group_count)) != 0)
+ {
+ critical_alert("AD incremental - user update",
+ "LDAP server couldn't process filesys %s : %s",
+ fs_name, ldap_err2string(rc));
+ goto cleanup;
+ }
+
+ if (group_count != 1)
+ {
+ critical_alert("AD incremental - user update",
+ "LDAP server unable to find user %s in AD.",
+ fs_name);
+ callback_rc = LDAP_NO_SUCH_OBJECT;
+ goto cleanup;
+ }
+ strcpy(distinguished_name, group_base->dn);
+
+ operation = LDAP_MOD_ADD;
+ if ((int)call_args[3] == ADFS_DELETE)
+ operation = LDAP_MOD_DELETE;
+
+ n = 0;
+ if (operation == LDAP_MOD_ADD)
+ {
+ memset(winPath, 0, sizeof(winPath));
+ AfsToWinAfs(av[FS_PACK], winPath);
+ homedir_v[0] = winPath;
+ drives_v[0] = "H:";
+ memset(winProfile, 0, sizeof(winProfile));
+ strcpy(winProfile, winPath);
+ strcat(winProfile, "\\.winprofile");
+ winProfile_v[0] = winProfile;
+ }
+ else
+ {
+ homedir_v[0] = NULL;
+ drives_v[0] = NULL;
+ winProfile_v[0] = NULL;
+ }
+ ADD_ATTR("profilePath", winProfile_v, operation);
+ ADD_ATTR("homeDrive", drives_v, operation);
+ ADD_ATTR("homeDirectory", homedir_v, operation);
+ mods[n] = NULL;
+
+ for (i = 1; i < 6; i++)
+ {
+ if ((rc = ldap_modify_s((LDAP *)call_args[0], distinguished_name, mods)) == LDAP_SUCCESS)
+ break;
+ sleep(20);
+ }
+ if (rc != LDAP_SUCCESS)
+ {
+ critical_alert("AD incremental - filesys update",
+ "Couldn't modify user data for filesys %s : %s",
+ fs_name, ldap_err2string(rc));
+ }
+ for (i = 0; i < n; i++)
+ free(mods[i]);
+
+cleanup:
+ return(0);
+}
+
int user_create(int ac, char **av, void *ptr)
{
LDAPMod *mods[20];
}
if (rc == LDAP_SUCCESS)
{
- if ((rc = set_password(sam_name, ldap_domain)) != 0)
+ if ((rc = set_password(sam_name, "", ldap_domain)) != 0)
{
- if ((rc = set_password(user_name, ldap_domain)) != 0)
- {
- critical_alert("AD incremental - user create",
- "Couldn't set password for user %s : %ld",
- user_name, rc);
- }
+ critical_alert("AD incremental - user create",
+ "Couldn't set password for user %s : %ld",
+ user_name, rc);
}
}
sprintf(filter_exp, "(sAMAccountName=%s)", av[U_NAME]);
if (status)
{
if (status == MR_UNKNOWN_PROC)
- {
- if (version > 2)
- status = MR_VERSION_HIGH;
- else
- status = MR_SUCCESS;
- }
+ {
+ 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.");
- }
+ {
+ 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;
- }
+ {
+ 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;
- }
+ {
+ com_err(whoami, status, "while authenticating to Moira.");
+ mr_disconnect();
+ return MRCL_AUTH_ERROR;
+ }
}
return MRCL_SUCCESS;
}
+void expand_groups(LDAP *ldap_handle, char *dn_path, char *group_name)
+{
+ LK_ENTRY *group_base = NULL;
+ LK_ENTRY *ptr = NULL;
+ char *call_args[7];
+ char *av[2];
+ int rc;
+ int before_count;
+ int after_count;
+
+ av[0] = "RLIST";
+ av[1] = group_name;
+ call_args[0] = (char *)ldap_handle;
+ call_args[1] = dn_path;
+ call_args[2] = group_name;
+ call_args[3] = NULL;
+
+ linklist_free(member_base);
+ member_base = NULL;
+ linklist_free(sid_base);
+ sid_base = NULL;
+ if (mr_query("get_lists_of_member", 2, av, list_list_build, call_args) == MR_NO_MATCH)
+ return;
+ if (member_base == NULL)
+ return;
+ while (1)
+ {
+ group_base = member_base;
+ ptr = group_base;
+ before_count = 0;
+ while(ptr != NULL)
+ {
+ ++before_count;
+ ptr = ptr->next;
+ }
+ ptr = group_base;
+ while (ptr != NULL)
+ {
+ av[0] = "RLIST";
+ av[1] = ptr->member;
+ call_args[0] = (char *)ldap_handle;
+ call_args[1] = dn_path;
+ call_args[2] = ptr->member;
+ call_args[3] = NULL;
+ mr_query("get_lists_of_member", 2, av, list_list_build, call_args);
+ ptr = ptr->next;
+ }
+ after_count = 0;
+ ptr = group_base;
+ while(ptr != NULL)
+ {
+ ++after_count;
+ ptr = ptr->next;
+ }
+ if (before_count == after_count)
+ break;
+ }
+
+ group_base = member_base;
+ ptr = group_base;
+ while (ptr != NULL)
+ {
+ member_base = NULL;
+ sid_base = NULL;
+ sid_ptr = &sid_base;
+ av[0] = ptr->member;
+ av[1] = NULL;
+ call_args[0] = (char *)ldap_handle;
+ call_args[1] = dn_path;
+ call_args[2] = ptr->member;
+ call_args[3] = NULL;
+ call_args[4] = NULL;
+ call_args[5] = NULL;
+ call_args[6] = (char *)(MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS);
+ if (rc = mr_query("get_list_info", 1, av, group_create, call_args))
+ {
+ linklist_free(member_base);
+ member_base = NULL;
+ ptr = ptr->next;
+ continue;
+ }
+ if (sid_base != NULL)
+ {
+ sid_update(ldap_handle, dn_path);
+ linklist_free(sid_base);
+ sid_base = NULL;
+ }
+ member_base = NULL;
+ if (!(rc = mr_query("get_end_members_of_list", 1, av, member_list_build,
+ call_args)))
+ {
+ if (member_base == NULL)
+ {
+ member_remove(ldap_handle, dn_path, ptr->member,
+ call_args[3], call_args[4], call_args[5]);
+ }
+ else
+ {
+ rc = member_list_process(ldap_handle, dn_path, ptr->member,
+ call_args[3], call_args[4], call_args[5],
+ MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS);
+ }
+ }
+ linklist_free(member_base);
+ member_base = NULL;
+ 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;
+ call_args[5] = NULL;
+ call_args[6] = NULL;
+ ptr = ptr->next;
+ }
+ linklist_free(group_base);
+ group_base = NULL;
+ return;
+}
+
+void AfsToWinAfs(char* path, char* winPath)
+{
+ char* pathPtr;
+ char* winPathPtr;
+ strcpy(winPath, WINAFS);
+ pathPtr = path + strlen(AFS);
+ winPathPtr = winPath + strlen(WINAFS);
+
+ while (*pathPtr)
+ {
+ if (*pathPtr == '/')
+ *winPathPtr = '\\';
+ else
+ *winPathPtr = *pathPtr;
+
+ pathPtr++;
+ winPathPtr++;
+ }
+}