static int decode_realms(krb5_context context, const char *tr, int length, struct tr_realm **realms) { struct tr_realm *r = NULL; char *tmp; int quote = 0; const char *start = tr; int i; for(i = 0; i < length; i++){ if(quote){ quote = 0; continue; } if(tr[i] == '\\'){ quote = 1; continue; } if(tr[i] == ','){ tmp = malloc(tr + i - start + 1); if(tmp == NULL){ krb5_set_error_string (context, "malloc: out of memory"); return ENOMEM; } memcpy(tmp, start, tr + i - start); tmp[tr + i - start] = '\0'; r = make_realm(tmp); if(r == NULL){ free_realms(*realms); krb5_set_error_string (context, "malloc: out of memory"); return ENOMEM; } *realms = append_realm(*realms, r); start = tr + i + 1; } } tmp = malloc(tr + i - start + 1); if(tmp == NULL){ free(*realms); krb5_set_error_string (context, "malloc: out of memory"); return ENOMEM; } memcpy(tmp, start, tr + i - start); tmp[tr + i - start] = '\0'; r = make_realm(tmp); if(r == NULL){ free_realms(*realms); krb5_set_error_string (context, "malloc: out of memory"); return ENOMEM; } *realms = append_realm(*realms, r); return 0; }
static int decode_realms(krb5_context context, const char *tr, size_t length, struct tr_realm **realms) { struct tr_realm *r = NULL; char *tmp; int quote = 0; const char *start = tr; int i; for(i = 0; i < length; i++){ if(quote){ quote = 0; continue; } if(tr[i] == '\\'){ quote = 1; continue; } if(tr[i] == ','){ tmp = malloc(tr + i - start + 1); if(tmp == NULL) return krb5_enomem(context); memcpy(tmp, start, tr + i - start); tmp[tr + i - start] = '\0'; r = make_realm(tmp); if(r == NULL){ free_realms(*realms); return krb5_enomem(context); } *realms = append_realm(*realms, r); start = tr + i + 1; } } tmp = malloc(tr + i - start + 1); if(tmp == NULL){ free(*realms); return krb5_enomem(context); } memcpy(tmp, start, tr + i - start); tmp[tr + i - start] = '\0'; r = make_realm(tmp); if(r == NULL){ free_realms(*realms); return krb5_enomem(context); } *realms = append_realm(*realms, r); return 0; }
static int make_paths(krb5_context context, struct tr_realm *realms, const char *client_realm, const char *server_realm) { struct tr_realm *r; int ret; const char *prev_realm = client_realm; const char *next_realm = NULL; for(r = realms; r; r = r->next){ /* it *might* be that you can have more than one empty component in a row, at least that's how I interpret the "," exception in 1510 */ if(r->realm[0] == '\0'){ while(r->next && r->next->realm[0] == '\0') r = r->next; if(r->next) next_realm = r->next->realm; else next_realm = server_realm; ret = make_path(context, r, prev_realm, next_realm); if(ret){ free_realms(realms); return ret; } } prev_realm = r->realm; } return 0; }
static int expand_realms(krb5_context context, struct tr_realm *realms, const char *client_realm) { struct tr_realm *r; const char *prev_realm = NULL; for(r = realms; r; r = r->next){ if(r->trailing_dot){ char *tmp; size_t len; if(prev_realm == NULL) prev_realm = client_realm; len = strlen(r->realm) + strlen(prev_realm) + 1; tmp = realloc(r->realm, len); if(tmp == NULL){ free_realms(realms); krb5_set_error_string (context, "malloc: out of memory"); return ENOMEM; } r->realm = tmp; strlcat(r->realm, prev_realm, len); }else if(r->leading_slash && !r->leading_space && prev_realm){ /* yet another exception: if you use x500-names, the leading realm doesn't have to be "quoted" with a space */ char *tmp; size_t len = strlen(r->realm) + strlen(prev_realm) + 1; tmp = malloc(len); if(tmp == NULL){ free_realms(realms); krb5_set_error_string (context, "malloc: out of memory"); return ENOMEM; } strlcpy(tmp, prev_realm, len); strlcat(tmp, r->realm, len); free(r->realm); r->realm = tmp; } prev_realm = r->realm; } return 0; }