This seems to work for your example data.
data want;
set have;
retain lstart lend;
lstart = coalesce(start,lstart);
lend = coalesce(end,lend);
start = coalesce(start,lstart);
end = coalesce(end,lend);
drop lstart lend;
run;
Retain will keep values across records. The Coalesce (and Coalescec for character values) returns the first non-missing value in the list and is basically used to avoid a bunch of similar "if missing(var) then var=varb;" type statements.
Note If you do NOT actually want to carry the dates forward with the ID changes then you need to state so and indicate what should be done. The above code ignores the ID.