krb5_error_code krb5_ldap_readpassword(krb5_context context, krb5_ldap_context *ldap_context, unsigned char **password) { int entryfound=0; krb5_error_code st=0; char line[RECORDLEN]="0", *start=NULL, *file=NULL; char errbuf[1024]; FILE *fptr=NULL; *password = NULL; if (ldap_context->service_password_file) file = ldap_context->service_password_file; #ifndef HAVE_STRERROR_R # undef strerror_r # define strerror_r(ERRNUM, BUF, SIZE) (strncpy(BUF, strerror(ERRNUM), SIZE), BUF[(SIZE)-1] = 0) #endif /* check whether file exists */ if (access(file, F_OK) < 0) { st = errno; strerror_r(errno, errbuf, sizeof(errbuf)); krb5_set_error_message (context, st, "%s", errbuf); goto rp_exit; } /* check read access */ if (access(file, R_OK) < 0) { st = errno; strerror_r(errno, errbuf, sizeof(errbuf)); krb5_set_error_message (context, st, "%s", errbuf); goto rp_exit; } if ((fptr=fopen(file, "r")) == NULL) { st = errno; strerror_r(errno, errbuf, sizeof(errbuf)); krb5_set_error_message (context, st, "%s", errbuf); goto rp_exit; } set_cloexec_file(fptr); /* get the record from the file */ while (fgets(line, RECORDLEN, fptr)!= NULL) { char tmp[RECORDLEN]; tmp[0] = '\0'; /* Handle leading white-spaces */ for (start = line; isspace(*start); ++start); /* Handle comment lines */ if (*start == '!' || *start == '#') continue; sscanf(line, "%*[ \t]%[^#]", tmp); if (tmp[0] == '\0') sscanf(line, "%[^#]", tmp); if (strcasecmp(tmp, ldap_context->bind_dn) == 0) { entryfound = 1; /* service_dn record found !!! */ break; } } fclose (fptr); if (entryfound == 0) { st = KRB5_KDB_SERVER_INTERNAL_ERR; krb5_set_error_message (context, st, "Bind DN entry missing in stash file"); goto rp_exit; } /* replace the \n with \0 */ start = strchr(line, '\n'); if (start) *start = '\0'; start = strchr(line, '#'); if (start == NULL) { /* password field missing */ st = KRB5_KDB_SERVER_INTERNAL_ERR; krb5_set_error_message (context, st, "Stash file entry corrupt"); goto rp_exit; } ++ start; /* Extract the plain password / certificate file information */ { struct data PT, CT; /* Check if the entry has the path of a certificate */ if (!strncmp(start, "{FILE}", strlen("{FILE}"))) { /* Set *password = {FILE}<path to cert>\0<cert password> */ size_t len = strlen(start); *password = (unsigned char *)malloc(len + 2); if (*password == NULL) { st = ENOMEM; goto rp_exit; } memcpy(*password, start, len); (*password)[len] = '\0'; (*password)[len + 1] = '\0'; goto got_password; } else { CT.value = (unsigned char *)start; CT.len = strlen((char *)CT.value); st = dec_password(CT, &PT); if (st != 0) { switch (st) { case ERR_NO_MEM: st = ENOMEM; break; case ERR_PWD_ZERO: st = EINVAL; krb5_set_error_message(context, st, "Password has zero length"); break; case ERR_PWD_BAD: st = EINVAL; krb5_set_error_message(context, st, "Password corrupted"); break; case ERR_PWD_NOT_HEX: st = EINVAL; krb5_set_error_message(context, st, "Not a hexadecimal password"); break; default: st = KRB5_KDB_SERVER_INTERNAL_ERR; break; } goto rp_exit; } *password = PT.value; } } got_password: rp_exit: if (st) { if (*password) free (*password); *password = NULL; } return st; }
krb5_error_code krb5_ldap_readpassword(krb5_context context, krb5_ldap_context *ldap_context, unsigned char **password) { int entryfound=0; krb5_error_code st=0; char line[RECORDLEN]="0", *start=NULL, *file=NULL; char errbuf[1024]; FILE *fptr=NULL; *password = NULL; if (ldap_context->service_password_file) file = ldap_context->service_password_file; #ifndef HAVE_STRERROR_R # undef strerror_r # define strerror_r(ERRNUM, BUF, SIZE) (strncpy(BUF, strerror(ERRNUM), SIZE), BUF[(SIZE)-1] = 0) #endif /* check whether file exists */ if (access(file, F_OK) < 0) { st = errno; strerror_r(errno, errbuf, sizeof(errbuf)); krb5_set_error_message (context, st, "%s", errbuf); goto rp_exit; } /* check read access */ if (access(file, R_OK) < 0) { st = errno; strerror_r(errno, errbuf, sizeof(errbuf)); krb5_set_error_message (context, st, "%s", errbuf); goto rp_exit; } if ((fptr=fopen(file, "r")) == NULL) { st = errno; strerror_r(errno, errbuf, sizeof(errbuf)); krb5_set_error_message (context, st, "%s", errbuf); goto rp_exit; } set_cloexec_file(fptr); /* get the record from the file */ while (fgets(line, RECORDLEN, fptr)!= NULL) { char tmp[RECORDLEN]; tmp[0] = '\0'; /* Handle leading white-spaces */ for (start = line; isspace(*start); ++start); /* Handle comment lines */ if (*start == '!' || *start == '#') continue; sscanf(line, "%*[ \t]%[^#]", tmp); if (tmp[0] == '\0') sscanf(line, "%[^#]", tmp); if (strcasecmp(tmp, ldap_context->bind_dn) == 0) { entryfound = 1; /* service_dn record found !!! */ break; } } fclose (fptr); if (entryfound == 0) { st = KRB5_KDB_SERVER_INTERNAL_ERR; krb5_set_error_message(context, st, _("Bind DN entry missing in stash file")); goto rp_exit; } /* replace the \n with \0 */ start = strchr(line, '\n'); if (start) *start = '\0'; start = strchr(line, '#'); if (start == NULL) { /* password field missing */ st = KRB5_KDB_SERVER_INTERNAL_ERR; krb5_set_error_message(context, st, _("Stash file entry corrupt")); goto rp_exit; } ++ start; /* Extract the plain password information. */ st = dec_password(context, start, password); rp_exit: if (st) { if (*password) free (*password); *password = NULL; } return st; }