From: zacheiss Date: Mon, 26 Jul 2004 20:16:41 +0000 (+0000) Subject: Changes from dtanner; build against MIT krb5 1.3. X-Git-Url: http://andersk.mit.edu/gitweb/moira.git/commitdiff_plain/26503e1586cd81e94470a22bd5244f70c578ffc5 Changes from dtanner; build against MIT krb5 1.3. --- diff --git a/incremental/winad/kpasswd.h b/incremental/winad/kpasswd.h index 37f19d72..300484af 100644 --- a/incremental/winad/kpasswd.h +++ b/incremental/winad/kpasswd.h @@ -6,9 +6,6 @@ Module Name: --*/ -krb5_error_code krb5_set_password - KRB5_PROTOTYPE((krb5_context, krb5_ccache, char *, char *, char *, int *)); - typedef struct _krb5_setpw { krb5_magic magic; krb5_data newpasswd; diff --git a/incremental/winad/setpw.c b/incremental/winad/setpw.c index 7e08b29c..4ea37971 100644 --- a/incremental/winad/setpw.c +++ b/incremental/winad/setpw.c @@ -50,10 +50,9 @@ Abstract: #include #ifdef _WIN32 #include -#include "k5-int.h" -#include "adm_err.h" #include "krb5_err.h" #else +#include "port-sockets.h" #include #include #include @@ -79,6 +78,8 @@ Abstract: #endif #ifdef _WIN32 +extern krb5_error_code decode_krb5_error + (const krb5_data *output, krb5_error **rep); #define sleep(Seconds) Sleep(Seconds * 1000) #define gethostbyname(Server) rgethostbyname(Server) #endif @@ -189,7 +190,7 @@ 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, char **ServerList, int *IgnoreServerListError); + int connect_to_kdc, char **ServerList); int ad_kdc_connect(char *connectedServer); int ad_server_connect(char *connectedServer, char *domain); void ad_kdc_disconnect(); @@ -201,8 +202,11 @@ int locate_ldap_server(char *domain, char **server_name); long myrandom(); void generate_password(char *password); + +#ifdef WIN32 krb5_error_code encode_krb5_setpw PROTOTYPE((const krb5_setpw *rep, krb5_data ** code)); +#endif krb5_error_code make_setpw_req(krb5_context context, krb5_auth_context auth_context, krb5_data *ap_req, krb5_principal targprinc, @@ -264,7 +268,6 @@ krb5_error_code get_setpw_rep(krb5_context context, krb5_auth_context auth_conte 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) @@ -282,7 +285,7 @@ krb5_error_code get_setpw_rep(krb5_context context, krb5_auth_context auth_conte /* verify length */ plen = (*ptr++ & 0xff); plen = (plen<<8) | (*ptr++ & 0xff); - if (plen != packet->length) + if (plen != (int)packet->length) return(KRB5KRB_AP_ERR_MODIFIED); vno = (*ptr++ & 0xff); vno = (vno<<8) | (*ptr++ & 0xff); @@ -307,11 +310,8 @@ krb5_error_code get_setpw_rep(krb5_context context, krb5_auth_context auth_conte /* 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); } @@ -465,7 +465,7 @@ krb5_error_code kdc_set_password(krb5_context context, krb5_ccache ccache, { if ((cc = sendto(kdc_socket, chpw_snd.data, chpw_snd.length, 0, NULL, - 0)) != chpw_snd.length) + 0)) != (int)chpw_snd.length) { code = KDC_SEND_ERROR; sleep(1); @@ -687,7 +687,7 @@ 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, char **ServerList, int *IgnoreServerListError) + int connect_to_kdc, char **ServerList) { int i; int k; @@ -699,19 +699,23 @@ int ad_connect(LDAP **ldap_handle, char *ldap_domain, char *dn_path, int Max_wait_time = 500; int Max_size_limit = LDAP_NO_LIMIT; - if (ldap_domain == NULL) - ldap_domain = "win.mit.edu"; + if (strlen(ldap_domain) == 0) + return(1); + convert_domain_to_dn(ldap_domain, dn_path); if (strlen(dn_path) == 0) - return(1); + return(1); Count = 0; while (ServerList[Count] != NULL) ++Count; + if ((Count == 0) && (connect_to_kdc)) + return(1); + memset(server_name, 0, sizeof(server_name[0]) * MAX_SERVER_NAMES); if (locate_ldap_server(ldap_domain, server_name) == -1) - return(2); + return(1); for (i = 0; i < MAX_SERVER_NAMES; i++) { @@ -766,6 +770,7 @@ int ad_connect(LDAP **ldap_handle, char *ldap_domain, char *dn_path, if (!ad_server_connect(ServerList[i], ldap_domain)) { ldap_unbind_s((*ldap_handle)); + (*ldap_handle) = NULL; continue; } } @@ -774,15 +779,14 @@ int ad_connect(LDAP **ldap_handle, char *ldap_domain, char *dn_path, strcpy(connected_server, ServerList[i]); break; } - } - if ((i == 0) && ((*IgnoreServerListError) == 0)) - { - (*IgnoreServerListError) = -1; - return(1); + else + { + (*ldap_handle) = NULL; + } } } - if (i >= MAX_SERVER_NAMES) - return(3); + if ((*ldap_handle) == NULL) + return(1); return(0); } diff --git a/incremental/winad/winad.c b/incremental/winad/winad.c index 5a5e4822..e8cf5990 100755 --- a/incremental/winad/winad.c +++ b/incremental/winad/winad.c @@ -114,7 +114,6 @@ #include #include #include -#include #include #include #include "kpasswd.h" @@ -204,8 +203,11 @@ typedef struct _SID { #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 QUERY_VERSION -1 +#define PRIMARY_REALM "ATHENA.MIT.EDU" +#define PRIMARY_DOMAIN "win.mit.edu" +#define PRODUCTION_PRINCIPAL "sms" +#define TEST_PRINCIPAL "smstest" #define SUBSTITUTE 1 #define REPLACE 2 @@ -294,11 +296,23 @@ typedef struct lk_entry { DelMods[i++]->mod_values = NULL #define DOMAIN_SUFFIX "MIT.EDU" -#define DOMAIN "DOMAIN: " -#define SERVER "SERVER: " -#define MSSFU "SFU: " +#define DOMAIN "DOMAIN:" +#define PRINCIPALNAME "PRINCIPAL:" +#define SERVER "SERVER:" +#define MSSFU "SFU:" #define SFUTYPE "30" +char PrincipalName[128]; +#ifndef _WIN32 +#define KRB5CCNAME "KRB5CCNAME=/tmp/krb5cc_winad.incr" +#define KRBTKFILE "KRBTKFILE=/tmp/tkt_winad.incr" +#define KEYTABFILE "/etc/krb5.keytab" +#else +#define KRB5CCNAME "KRB5CCNAME=\\tmp\\krb5cc_winad.incr" +#define KRBTKFILE "KRBTKFILE=\\tmp\\tkt_winad.incr" +#define KEYTABFILE "\\keytabs\\krb5.keytab" +#endif + LK_ENTRY *member_base = NULL; LK_ENTRY *sid_base = NULL; LK_ENTRY **sid_ptr = NULL; @@ -322,6 +336,7 @@ int callback_rc; char default_server[256]; static char tbl_buf[1024]; int UseSFU30 = 0; +int NoChangeConfigFile; extern int set_password(char *user, char *password, char *domain); @@ -332,8 +347,9 @@ int ad_get_group(LDAP *ldap_handle, char *dn_path, char *group_name, 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, char **ServerList, int *IgnoreMasterSeverError); + int connect_to_kdc, char **ServerList); void ad_kdc_disconnect(); +int ad_server_connect(char *connectedServer, char *domain); int attribute_update(LDAP *ldap_handle, char *distinguished_name, char *attribute_value, char *attribute, char *user_name); int BEREncodeSecurityBits(ULONG uBits, char *pBuffer); @@ -384,6 +400,8 @@ int process_lists(int ac, char **av, void *ptr); int ProcessGroupSecurity(LDAP *ldap_handle, char *dn_path, char *TargetGroupName, int HiddenGroup, char *AceType, char *AceName); int ProcessMachineName(int ac, char **av, void *ptr); +void ReadConfigFile(); +void StringTrim(char *StringToTrim); int user_create(int ac, char **av, void *ptr); int user_change_status(LDAP *ldap_handle, char *dn_path, char *user_name, char *MoiraId, int operation); @@ -473,6 +491,10 @@ int moira_disconnect(void); int moira_connect(void); void print_to_screen(const char *fmt, ...); int GetMachineName(char *MachineName); +int tickets_get_k5(); +int get_tickets(); +int destroy_cache(void); +int dest_tkt(void); int main(int argc, char **argv) { @@ -481,17 +503,12 @@ int main(int argc, char **argv) int afterc; int i; int j; - int Count; - int k; int OldUseSFU30; - int IgnoreServerListError; char *table; char **before; char **after; LDAP *ldap_handle; - FILE *fptr; char dn_path[256]; - char temp[32]; whoami = ((whoami = (char *)strrchr(argv[0], '/')) ? whoami+1 : argv[0]); @@ -525,113 +542,51 @@ int main(int argc, char **argv) } com_err(whoami, 0, "%s", tbl_buf); - check_winad(); - + memset(PrincipalName, '\0', sizeof(PrincipalName)); memset(ldap_domain, '\0', sizeof(ldap_domain)); memset(ServerList, '\0', sizeof(ServerList[0]) * MAX_SERVER_NAMES); - memset(temp, '\0', sizeof(temp)); UseSFU30 = 0; - OldUseSFU30 = 0; - Count = 0; + NoChangeConfigFile = 0; - if ((fptr = fopen(WINADCFG, "r")) != NULL) - { - while (fgets(temp, sizeof(temp), fptr) != 0) - { - for (i = 0; i < (int)strlen(temp); i++) - temp[i] = toupper(temp[i]); - if (temp[strlen(temp) - 1] == '\n') - temp[strlen(temp) - 1] = '\0'; - if (!strncmp(temp, DOMAIN, strlen(DOMAIN))) - { - if (strlen(temp) > (strlen(DOMAIN))) - { - strcpy(ldap_domain, &temp[strlen(DOMAIN)]); - } - } - else if (!strncmp(temp, SERVER, strlen(SERVER))) - { - if (strlen(temp) > (strlen(SERVER))) - { - ServerList[Count] = calloc(1, 256); - strcpy(ServerList[Count], &temp[strlen(SERVER)]); - ++Count; - } - } - else if (!strncmp(temp, MSSFU, strlen(MSSFU))) - { - if (strlen(temp) > (strlen(MSSFU))) - { - if (!strcmp(&temp[strlen(MSSFU)], SFUTYPE)) - UseSFU30 = 1; - } - } - else - { - strcpy(ldap_domain, temp); - } - } - fclose(fptr); - } + check_winad(); + + ReadConfigFile(); + OldUseSFU30 = UseSFU30; - if (strlen(ldap_domain) == 0) - strcpy(ldap_domain, "win.mit.edu"); - /* zero trailing newline, if there is one. */ - if (ldap_domain[strlen(ldap_domain) - 1] == '\n') - ldap_domain[strlen(ldap_domain) - 1] = '\0'; + get_tickets(); initialize_sms_error_table(); initialize_krb_error_table(); - IgnoreServerListError = 0; - if (ServerList[0] == NULL) - { - IgnoreServerListError = 1; - GetServerList(ldap_domain, ServerList); - } - for (i = 0; i < MAX_SERVER_NAMES; i++) - { - if (ServerList[i] != 0) - { - if (ServerList[i][strlen(ServerList[i]) - 1] == '\n') - ServerList[i][strlen(ServerList[i]) - 1] = '\0'; - strcat(ServerList[i], "."); - strcat(ServerList[i], ldap_domain); - for (k = 0; k < (int)strlen(ServerList[i]); k++) - ServerList[i][k] = toupper(ServerList[i][k]); - } - } - memset(default_server, '\0', sizeof(default_server)); memset(dn_path, '\0', sizeof(dn_path)); for (i = 0; i < 5; i++) { + ldap_handle = (LDAP *)NULL; if (!(rc = ad_connect(&ldap_handle, ldap_domain, dn_path, "", "", - default_server, 1, ServerList, &IgnoreServerListError))) + default_server, 1, ServerList))) break; - if (IgnoreServerListError < 0) + if (ldap_handle == NULL) { - GetServerList(ldap_domain, ServerList); - for (j = 0; j < MAX_SERVER_NAMES; j++) + if (!NoChangeConfigFile) { - if (ServerList[j] != NULL) + for (j = 0; j < MAX_SERVER_NAMES; j++) { - if (ServerList[j][strlen(ServerList[j]) - 1] == '\n') - ServerList[j][strlen(ServerList[j]) - 1] = '\0'; - strcat(ServerList[j], "."); - strcat(ServerList[j], ldap_domain); - for (k = 0; k < (int)strlen(ServerList[j]); k++) - ServerList[j][k] = toupper(ServerList[j][k]); + if (ServerList[j] != NULL) + { + free(ServerList[j]); + ServerList[j] = NULL; + } } + GetServerList(ldap_domain, ServerList); } - IgnoreServerListError = 1; - --i; } - sleep(2); } - if (rc) + + if ((rc) || (ldap_handle == NULL)) { critical_alert("incremental", "winad.incr cannot connect to any server in domain %s", ldap_domain); + destroy_cache(); exit(1); } @@ -658,7 +613,8 @@ int main(int argc, char **argv) afterc); if (OldUseSFU30 != UseSFU30) { - GetServerList(ldap_domain, ServerList); + if (!NoChangeConfigFile) + GetServerList(ldap_domain, ServerList); } ad_kdc_disconnect(); for (i = 0; i < MAX_SERVER_NAMES; i++) @@ -670,6 +626,7 @@ int main(int argc, char **argv) } } rc = ldap_unbind_s(ldap_handle); + destroy_cache(); exit(0); } @@ -3374,8 +3331,21 @@ int user_create(int ac, char **av, void *ptr) { if ((rc = set_password(sam_name, "", ldap_domain)) != 0) { - com_err(whoami, 0, "Unable to set password for user %s : %ld", - user_name, rc); + ad_kdc_disconnect(); + tickets_get_k5(); + if (!ad_server_connect(default_server, ldap_domain)) + { + com_err(whoami, 0, "Unable to set password for user %s : %s", + user_name, "cannot get changepw ticket from windows domain"); + } + else + { + if ((rc = set_password(sam_name, "", ldap_domain)) != 0) + { + com_err(whoami, 0, "Unable to set password for user %s : %ld", + user_name, rc); + } + } } } sprintf(filter, "(sAMAccountName=%s)", av[U_NAME]); @@ -5825,7 +5795,7 @@ int GetServerList(char *ldap_domain, char **ServerList) int UseSFU30; int Count; int i; - int IgnoreServerListError; + int k; int ServerListFound; char default_server[256]; char dn_path[256]; @@ -5848,9 +5818,8 @@ int GetServerList(char *ldap_domain, char **ServerList) ServerList[i] = NULL; } } - IgnoreServerListError = 1; if (rc = ad_connect(&ldap_handle, ldap_domain, dn_path, "", "", default_server, 0, - ServerList, &IgnoreServerListError)) + ServerList)) return(1); memset(ServerList, '\0', sizeof(ServerList[0]) * MAX_SERVER_NAMES); group_count = 0; @@ -5940,20 +5909,35 @@ int GetServerList(char *ldap_domain, char **ServerList) if ((fptr = fopen(WINADCFG, "w+")) != NULL) { - fprintf(fptr, "%s%s\n", DOMAIN, ldap_domain); + fprintf(fptr, "%s %s\n", DOMAIN, ldap_domain); + if (strlen(PrincipalName) != 0) + fprintf(fptr, "%s %s\n", PRINCIPALNAME, PrincipalName); if (UseSFU30) - fprintf(fptr, "%s%s\n", MSSFU, SFUTYPE); + fprintf(fptr, "%s %s\n", MSSFU, SFUTYPE); for (i = 0; i < MAX_SERVER_NAMES; i++) { if (ServerList[i] != NULL) { - fprintf(fptr, "%s%s\n", SERVER, ServerList[i]); + fprintf(fptr, "%s %s\n", SERVER, ServerList[i]); } } fclose(fptr); } ldap_unbind_s(ldap_handle); + for (i = 0; i < MAX_SERVER_NAMES; i++) + { + if (ServerList[i] != NULL) + { + if (ServerList[i][strlen(ServerList[i]) - 1] == '\n') + ServerList[i][strlen(ServerList[i]) - 1] = '\0'; + strcat(ServerList[i], "."); + strcat(ServerList[i], ldap_domain); + for (k = 0; k < (int)strlen(ServerList[i]); k++) + ServerList[i][k] = toupper(ServerList[i][k]); + } + } + return(0); } @@ -5998,3 +5982,205 @@ int attribute_update(LDAP *ldap_handle, char *distinguished_name, } return(rc); } + +int tickets_get_k5() +{ + char temp[128]; + char KinitPath[128]; + int retval; + int i; + static char EnvVar[128]; + static char EnvVar1[128]; + + strcpy(EnvVar, KRB5CCNAME); + retval = putenv(EnvVar); + strcpy(EnvVar1, KRBTKFILE); + retval = putenv(EnvVar1); + + for (i = 0; i < (int)strlen(PrincipalName); i++) + PrincipalName[i] = tolower(PrincipalName[i]); + if (strlen(PrincipalName) == 0) + { + strcpy(PrincipalName, PRODUCTION_PRINCIPAL); + if (strcmp(ldap_domain, PRIMARY_DOMAIN)) + strcpy(PrincipalName, TEST_PRINCIPAL); + } + + memset(KinitPath, '\0',sizeof(KinitPath)); +#ifndef _WIN32 + strcpy(KinitPath, "/usr/athena/bin/"); +#endif + sprintf(temp, "%skinit -k -t %s %s", KinitPath, KEYTABFILE, PrincipalName); + retval = system(temp); + if (retval) + return(-1); + return(0); +} + +int get_tickets() +{ + + if (tickets_get_k5()) + { + sleep(1); + if (tickets_get_k5()) + { + critical_alert("AD incremental", "%s", + "winad.incr incremental failed (unable to get kerberos tickets)"); + exit(1); + } + } + return(0); +} + +int destroy_cache(void) +{ + krb5_context context; + krb5_ccache cache; + krb5_error_code rc; + + context = NULL; + cache = NULL; + if (!krb5_init_context(&context)) + { + if (!krb5_cc_default(context, &cache)) + rc = krb5_cc_destroy(context, cache); + } + if (context != NULL) + krb5_free_context(context); + dest_tkt(); + + return(rc); +} + + +void StringTrim(char *StringToTrim) +{ + char *cPtr; + char temp[256]; + int i; + + if (strlen(StringToTrim) == 0) + return; + + cPtr = StringToTrim; + while (isspace(*cPtr)) + { + ++cPtr; + } + strcpy(temp, cPtr); + if (strlen(temp) == 0) + { + strcpy(StringToTrim, temp); + return; + } + while (1) + { + i = strlen(temp); + if (i == 0) + break; + if (!isspace(temp[i-1])) + break; + temp[i-1] = '\0'; + } + + strcpy(StringToTrim, temp); + return; +} + +void ReadConfigFile() +{ + int Count; + int i; + int k; + char temp[256]; + char temp1[256]; + FILE *fptr; + + Count = 0; + + if ((fptr = fopen(WINADCFG, "r")) != NULL) + { + while (fgets(temp, sizeof(temp), fptr) != 0) + { + for (i = 0; i < (int)strlen(temp); i++) + temp[i] = toupper(temp[i]); + if (temp[strlen(temp) - 1] == '\n') + temp[strlen(temp) - 1] = '\0'; + StringTrim(temp); + if (strlen(temp) == 0) + continue; + if (!strncmp(temp, DOMAIN, strlen(DOMAIN))) + { + if (strlen(temp) > (strlen(DOMAIN))) + { + strcpy(ldap_domain, &temp[strlen(DOMAIN)]); + StringTrim(ldap_domain); + } + } + else if (!strncmp(temp, PRINCIPALNAME, strlen(PRINCIPALNAME))) + { + if (strlen(temp) > (strlen(PRINCIPALNAME))) + { + strcpy(PrincipalName, &temp[strlen(PRINCIPALNAME)]); + StringTrim(PrincipalName); + } + } + else if (!strncmp(temp, SERVER, strlen(SERVER))) + { + if (strlen(temp) > (strlen(SERVER))) + { + ServerList[Count] = calloc(1, 256); + strcpy(ServerList[Count], &temp[strlen(SERVER)]); + StringTrim(ServerList[Count]); + ++Count; + } + } + else if (!strncmp(temp, MSSFU, strlen(MSSFU))) + { + if (strlen(temp) > (strlen(MSSFU))) + { + strcpy(temp1, &temp[strlen(MSSFU)]); + StringTrim(temp1); + if (!strcmp(temp1, SFUTYPE)) + UseSFU30 = 1; + } + } + else if (!strcasecmp(temp, "NOCHANGE")) + { + NoChangeConfigFile = 1; + } + else + { + if (strlen(ldap_domain) != 0) + { + memset(ldap_domain, '\0', sizeof(ldap_domain)); + break; + } + if (strlen(temp) != 0) + strcpy(ldap_domain, temp); + } + } + fclose(fptr); + } + + if (strlen(ldap_domain) == 0) + { + critical_alert("incremental", "%s", + "winad.incr cannot run due to a configuration error in winad.cfg"); + exit(1); + } + if (Count == 0) + return; + for (i = 0; i < Count; i++) + { + if (ServerList[i] != 0) + { + strcat(ServerList[i], "."); + strcat(ServerList[i], ldap_domain); + for (k = 0; k < (int)strlen(ServerList[i]); k++) + ServerList[i][k] = toupper(ServerList[i][k]); + } + } + +}