--- usermode-1.85/userhelper-wrap.c.user_authen 2006-01-03 11:53:03.000000000 +0100 +++ usermode-1.85/userhelper-wrap.c 2006-05-15 16:56:26.000000000 +0200 @@ -791,7 +791,7 @@ if (resp->responses == 0) { text = NULL; } else - if (resp->service) { + if (resp->service && strcmp(resp->service, "simple_root_authen")) { if (strcmp(resp->service, "passwd") == 0) { text = NULL; } else --- usermode-1.85/userhelper.c.user_authen 2006-05-15 16:56:26.000000000 +0200 +++ usermode-1.85/userhelper.c 2006-05-15 17:02:17.000000000 +0200 @@ -53,6 +53,8 @@ #endif +static int simple_root_authen = 0; + #include "shvar.h" #include "userhelper.h" @@ -1733,7 +1735,7 @@ /* We're here to wrap the named program. After authenticating as the * user given in the console.apps configuration file, execute the * command given in the console.apps file. */ - char *constructed_path; + char *constructed_path = NULL; char *apps_filename; char *user_pam; const char *auth_user; @@ -1753,7 +1755,7 @@ char *env_lcmonetary, *env_browser, *env_session_manager; int session, tryagain, gui, retval; struct stat sbuf; - struct passwd *pwd; + struct passwd *pwd = NULL; struct app_data *data; shvarFile *s; @@ -1930,6 +1932,7 @@ /* If the file is world-writable, or isn't a regular file, or couldn't * be opened, just exit. We don't want to alert an attacker that the * service name is invalid. */ + data = conv->appdata_ptr; if ((s == NULL) || (fstat(s->fd, &sbuf) == -1) || !S_ISREG(sbuf.st_mode) || @@ -1937,37 +1940,17 @@ #ifdef DEBUG_USERHELPER g_print("userhelper: bad file permissions: %s \n", apps_filename); #endif - exit(ERR_UNK_ERROR); - } + simple_root_authen = 1; + user_pam = "root"; + data->fallback_allowed = FALSE; + session = 1; + tryagain = 3; + } else { - data = conv->appdata_ptr; user_pam = get_user_for_auth(s); /* Read the path to the program to run. */ constructed_path = svGetValue(s, "PROGRAM"); - if (!constructed_path || constructed_path[0] != '/') { - /* Criminy.... The system administrator didn't give us an - * absolute path to the program! Guess either /usr/sbin or - * /sbin, and then give up if we don't find anything by that - * name in either of those directories. FIXME: we're a setuid - * app, so access() may not be correct here, as it may give - * false negatives. But then, it wasn't an absolute path. */ - constructed_path = g_strdup_printf("/usr/sbin/%s", program); - if (access(constructed_path, X_OK) != 0) { - /* Try the second directory. */ - strcpy(constructed_path, "/sbin/"); - strcat(constructed_path, program); - if (access(constructed_path, X_OK)) { - /* Nope, not there, either. */ -#ifdef DEBUG_USERHELPER - g_print("userhelper: couldn't find " - "wrapped binary\n"); -#endif - exit(ERR_NO_PROGRAM); - } - } - } - /* We can forcefully disable the GUI from the configuration * file (a la blah-nox applications). */ @@ -2001,24 +1984,6 @@ exit(ERR_NO_USER); } - /* If the user we're authenticating as has root's UID, then it's - * safe to let them use HOME=~root. */ - if (pwd->pw_uid == 0) { - setenv("HOME", g_strdup(pwd->pw_dir), 1); - } else { - /* Otherwise, if they had a reasonable value for HOME, let them - * use it. */ - if (env_home != NULL) { - setenv("HOME", env_home, 1); - } else { - /* Otherwise, set HOME to the user's home directory. */ - pwd = getpwuid(getuid()); - if ((pwd != NULL) && (pwd->pw_dir != NULL)) { - setenv("HOME", g_strdup(pwd->pw_dir), 1); - } - } - } - /* Read other settings. */ session = svTrueValue(s, "SESSION", FALSE); data->fallback_allowed = svTrueValue(s, "FALLBACK", FALSE); @@ -2077,9 +2042,55 @@ /* Now we're done reading the file. Close it. */ svCloseFile(s); + } + + if (!constructed_path || constructed_path[0] != '/') { + /* Criminy.... The system administrator didn't give + * us an absolute path to the program! Guess either + * /usr/sbin or /sbin, and then give up if there's + * nothing in either of those directories. */ + constructed_path = g_strdup_printf("/usr/sbin/%s", + program); + if (access(constructed_path, X_OK) != 0) { + /* Try the second directory. */ + strcpy(constructed_path, "/sbin/"); + strcat(constructed_path, program); + if (access(constructed_path, X_OK)) { + /* Nope, not there, either. */ +#ifdef DEBUG_USERHELPER + g_print("userhelper: couldn't find binary\n"); +#endif + exit(ERR_NO_PROGRAM); + } + } + } + + /* If the user we're authenticating as has root's UID, then it's + * safe to let them use HOME=~root. */ + if (pwd && pwd->pw_uid == 0) { + setenv("HOME", g_strdup(pwd->pw_dir), 1); + } else { + /* Otherwise, if they had a reasonable value for HOME, + * let them use it. */ + if (env_home) { + setenv("HOME", env_home, 1); + } else { + /* Otherwise, punt. */ + pwd = getpwuid(getuid()); + if ((pwd != NULL) && (pwd->pw_dir != NULL)) { + setenv("HOME", g_strdup(pwd->pw_dir), 1); + } + } + } + /* Start up PAM to authenticate the specified user. */ - retval = pam_start(program, user_pam, conv, &data->pamh); + if (simple_root_authen) { + retval = pam_start("simple_root_authen", user_pam, conv,&data->pamh); + } else { + retval = pam_start(program, user_pam, conv, &data->pamh); + } + if (retval != PAM_SUCCESS) { #ifdef DEBUG_USERHELPER g_print("userhelper: pam_start() failed\n");