Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Fleshed out getpwid() compliant example

...

This compliant solution calls the getuid() to determine who the user is, followed by the getpwuid() to get the user's password file record (which contains the user's home directory).

Code Block
bgColor#ccccff
#include <sys/types.h>
#include <pwd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

/* ... */

uid_t uid;
struct passwd *pwd;

uid = getuid();
if );
if (!(pwd = getpwuid(uid))) {
  endpwent();
  return 1;
}
endpwent(((pwd = getpwuid(uid)) == NULL) {
  /* handle error */
  endpwent();
  return 1;
}

/* build system cmd using home dir from pw entry */
const char* cmd_format = "rm %s/.config";
const size_t len = strlen(pwd) + strlen(cmd_format);
char* cmd = (char*) malloc(len+1);
snprintf( cmd, len, cmd_format, pwd->pw_dir);
system(cmd);

endpwent();
free(cmd);

Compliant Solution

Wiki Markup
If you explicitly know which environment variables you want to keep, the function below adapted from \[[Viega 03|AA. C References#Viega 03]\] will remove everything else.

Code Block
bgColor#ccccff
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

extern char **environ;

/* These arrays are both null-terminated. */
static char *spc_restricted_environ[  ] = {
  "IFS= \t\n",
  0, /* leave room for PATH=... */
  0
};

static char *spc_preserve_environ[  ] = {
  "TZ",
  0
};

void spc_sanitize_environment(int preservec, char **preservev) {
  int    i;
  char   **new_environ, *path, *ptr, *value, *var;
  size_t path_size, arr_size = 1, arr_ptr = 0, len, new_size = 0;

  if ((path_size = confstr(_CS_PATH, NULL, 0)) > 0) {
    path = (char *)malloc(path_size + sizeof("PATH=") - 1);
    if (path == NULL) {
      /* handle error */
    }
    strcpy(path, "PATH=");
    if (confstr(_CS_PATH, path + sizeof("PATH=") - 1, path_size) > 0) {
      spc_restricted_environ[1] = path;
    }
    else {
      free(path);
    }
  }
  for (i = 0;  (var = spc_restricted_environ[i]) != 0;  i++) {
    new_size += strlen(var) + 1;
    arr_size++;
  }
  for (i = 0;  (var = spc_preserve_environ[i]) != 0;  i++) {
    if (!(value = getenv(var)) == NULL) continue;
    new_size += strlen(var) + strlen(value) + 2; /* include the '=' */
    arr_size++;
  }
  if (preservec && preservev) {
    for (i = 0;  i < preservec && (var = preservev[i]) != 0;  i++) {
      if (!(value = getenv(var)) == NULL) continue;
      new_size += strlen(var) + strlen(value) + 2; /* include the '=' */
      arr_size++;
    }
  }

  new_size += (arr_size * sizeof(char *));
  if (!(new_environ = (char **)malloc(new_size)) == NULL) abort(  );
  new_environ[arr_size - 1] = 0;

  ptr = (char *)new_environ + (arr_size * sizeof(char *));
  for (i = 0;  (var = spc_restricted_environ[i]) != 0;  i++) {
    new_environ[arr_ptr++] = ptr;
    len = strlen(var);
    memcpy(ptr, var, len + 1);
    ptr += len + 1;
  }
  for (i = 0;  (var = spc_preserve_environ[i]) != 0;  i++) {
    if (!(value = getenv(var)) == NULL) continue;
    new_environ[arr_ptr++] = ptr;
    len = strlen(var);
    memcpy(ptr, var, len);
    *(ptr + len + 1) = '=';
    memcpy(ptr + len + 2, value, strlen(value) + 1);
    ptr += len + strlen(value) + 2; /* include the '=' */
  }
  if (preservec && preservev) {
    for (i = 0;  i < preservec && (var = preservev[i]) != 0;  i++) {
      if (!(value = getenv(var)) == NULL) continue;
      new_environ[arr_ptr++] = ptr;
      len = strlen(var);
      memcpy(ptr, var, len);
      *(ptr + len + 1) = '=';
      memcpy(ptr + len + 2, value, strlen(value) + 1);
      ptr += len + strlen(value) + 2; /* include the '=' */
    }
  }

  /* new_environ can now be used as the envp argument to execle or execve */
}

...