There are multiple issues:
void foo(char *foo, int baa)
{
    if (baa) 
        foo = "ab";
    else 
        foo = "cb";
}
This code changes the local pointer, but does nothing with it.  To copy strings around, you need to use strcpy() to keep the interface the same:
void foo(char *foo, int baa)
{
    if (baa) 
        strcpy(foo, "ab");
    else 
        strcpy(foo, "cb");
}
However, before doing that, you'd need to ensure that foo in the function points at modifiable memory.  The calling code needs to be modified to ensure that:
char x[] = "baa";
foo(x, 1);
printf("%s\n", x);
Alternatively, you can keep x as a pointer and revise the function interface:
void foo(char **foo, int baa)
{
    if (baa) 
        *foo = "ab";
    else 
        *foo = "cb";
}
and the calling sequence:
char *x = "baa";
foo(&x, 1);
printf("%s\n", x);
Both mechanisms work, but do so in their different ways.  There are different sets of issues with each.  There isn't a single 'this is better than that' decision; which is better depends on circumstances outside the scope of the code fragments shown.