gboolean mdm_common_is_action_available (gchar *action) { gchar **allowsyscmd = NULL; const gchar *allowsyscmdval; gboolean ret = FALSE; int i; allowsyscmdval = mdm_config_get_string (MDM_KEY_SYSTEM_COMMANDS_IN_MENU); if (allowsyscmdval) allowsyscmd = g_strsplit (allowsyscmdval, ";", 0); if (allowsyscmd) { for (i = 0; allowsyscmd[i] != NULL; i++) { if (strcmp (allowsyscmd[i], action) == 0) { ret = TRUE; break; } } } #ifdef HAVE_CHKAUTHATTR if (ret == TRUE) { gchar **rbackeys = NULL; const gchar *rbackeysval; const char *mdmuser; mdmuser = mdm_config_get_string (MDM_KEY_USER); rbackeysval = mdm_config_get_string (MDM_KEY_RBAC_SYSTEM_COMMAND_KEYS); if (rbackeysval) rbackeys = g_strsplit (rbackeysval, ";", 0); if (rbackeys) { for (i = 0; rbackeys[i] != NULL; i++) { gchar **rbackey = g_strsplit (rbackeys[i], ":", 2); if (mdm_vector_len (rbackey) == 2 && ! ve_string_empty (rbackey[0]) && ! ve_string_empty (rbackey[1]) && strcmp (rbackey[0], action) == 0) { if (!chkauthattr (rbackey[1], mdmuser)) { g_strfreev (rbackey); ret = FALSE; break; } } g_strfreev (rbackey); } } g_strfreev (rbackeys); } #endif g_strfreev (allowsyscmd); return ret; }
static boolean_t smbadm_checkauth(const char *auth) { struct passwd *pw; if ((pw = getpwuid(getuid())) == NULL) return (B_FALSE); if (chkauthattr(auth, pw->pw_name) == 0) return (B_FALSE); return (B_TRUE); }
/* * check_auth() * * Perform an RBAC authorization check. */ static int check_auth(ucred_t *ucred, const char *auth) { struct passwd pwd; uid_t euid; char buf[MAXPATHLEN]; euid = ucred_geteuid(ucred); if ((getpwuid_r(euid, &pwd, buf, sizeof (buf)) == NULL) || (chkauthattr(auth, pwd.pw_name) == 0)) { log_info("Unauthorized door call.\n"); return (-1); } return (0); }
/* * pm_poweroff - similar to poweroff(1M) * This should do the same auditing as poweroff(1m) would do when it * becomes a libpower function. Till then we use poweroff(1m). */ static void pm_poweroff(void) { if (chkauthattr(AUTHNAME_SHUTDOWN, user) != 1) { (void) printf(gettext("User %s does not have correct " "authorizations to shutdown this machine.\n"), user); exit(1); } openlog("suspend", 0, LOG_DAEMON); syslog(LOG_NOTICE, "System is being shut down."); closelog(); /* * Call poweroff(1m) to shut down the system. */ (void) execl("/usr/sbin/poweroff", "poweroff", NULL); }
/* * vs_stats_check_auth * * Returns: 0 caller authorized to reset stats * -1 caller not authorized to reset stats */ static int vs_stats_check_auth() { ucred_t *uc = NULL; uid_t uid; struct passwd *pw; if (door_ucred(&uc) != 0) return (-1); if (((uid = ucred_getsuid(uc)) == (uid_t)-1) || ((pw = getpwuid(uid)) == NULL) || (chkauthattr(VS_VALUE_AUTH, pw->pw_name) != 1)) { ucred_free(uc); return (-1); } ucred_free(uc); return (0); }
int check_auth(uid_t uid) { struct passwd *pw; pw = getpwuid(uid); if (pw == NULL) { /* fail if we cannot get password entry */ return (0); } /* * check in the RBAC authority files to see if * the user has permission to use CDRW */ if (chkauthattr(CDRW_AUTH, pw->pw_name) != 1) { /* user is not in database, return failure */ return (0); } else { return (1); } }
int main(int argc, char *argv[], char *envp[]) { struct passwd *pw = getpwuid(getuid()); char **newargv; int j; if (pw && chkauthattr(MAILQ_AUTH, pw->pw_name)) { /* The extra 2 is 1 for the "-bp" + 1 for the terminator. */ newargv = (char **)malloc((argc + 2) * sizeof (char *)); if (newargv == NULL) exit(EX_UNAVAILABLE); newargv[0] = _PATH_SENDMAIL_BIN; newargv[1] = "-bp"; for (j = 1; j <= argc; j++) newargv[j + 1] = argv[j]; (void) execve(_PATH_SENDMAIL_BIN, newargv, envp); perror("Cannot exec " _PATH_SENDMAIL_BIN); exit(EX_OSERR); } (void) fputs("No authorization to run mailq; " "see mailq(1) for details.\n", stderr); return (EX_NOPERM); }
/* ARGSUSED */ void ipmgmt_handler(void *cookie, char *argp, size_t argsz, door_desc_t *dp, uint_t n_desc) { ipmgmt_door_info_t *infop = NULL; ipmgmt_retval_t retval; int i; uint_t err; ucred_t *cred = NULL; for (i = 0; i_ipmgmt_door_info_tbl[i].idi_cmd != 0; i++) { if (i_ipmgmt_door_info_tbl[i].idi_cmd == ((ipmgmt_arg_t *)(void *)argp)->ia_cmd) { infop = &i_ipmgmt_door_info_tbl[i]; break; } } if (infop == NULL) { ipmgmt_log(LOG_ERR, "Invalid door command specified"); err = EINVAL; goto fail; } /* check for solaris.network.interface.config authorization */ if (infop->idi_set) { uid_t uid; struct passwd pwd; char buf[1024]; if (door_ucred(&cred) != 0) { err = errno; ipmgmt_log(LOG_ERR, "Could not get user credentials."); goto fail; } uid = ucred_getruid(cred); if ((int)uid < 0) { err = errno; ipmgmt_log(LOG_ERR, "Could not get user id."); goto fail; } if (getpwuid_r(uid, &pwd, buf, sizeof (buf)) == NULL) { err = errno; ipmgmt_log(LOG_ERR, "Could not get password entry."); goto fail; } if (chkauthattr(NETWORK_INTERFACE_CONFIG_AUTH, pwd.pw_name) != 1) { err = EPERM; ipmgmt_log(LOG_ERR, "Not authorized for operation."); goto fail; } ucred_free(cred); } /* individual handlers take care of calling door_return */ infop->idi_handler((void *)argp); return; fail: ucred_free(cred); retval.ir_err = err; (void) door_return((char *)&retval, sizeof (retval), NULL, 0); }
int main(int argc, char **argv) { int c; char display_name[MAXNAMELEN + 9] = "DISPLAY="; char xauthority[MAXPATHLEN + 12] = "XAUTHORITY="; struct passwd *pw; (void) signal(SIGHUP, SIG_IGN); (void) signal(SIGINT, SIG_IGN); (void) signal(SIGQUIT, SIG_IGN); (void) signal(SIGTSTP, SIG_IGN); (void) signal(SIGTTIN, SIG_IGN); (void) signal(SIGTTOU, SIG_IGN); /* * If suspend is invoked from a daemon (case 1 above), it * will not have a working stdin, stdout and stderr. We need * these to print proper error messages and possibly get user * input. We attach them to console and hope that attachment * works. */ if (ttyname(0) == NULL) { no_tty = 1; (void) dup2(open("/dev/console", O_RDONLY), 0); (void) dup2(open("/dev/console", O_WRONLY), 1); (void) dup2(open("/dev/console", O_WRONLY), 2); } while ((c = getopt(argc, argv, "fnxhtd:")) != EOF) { switch (c) { case 'f': /* * Force machine to poweroff if * suspend fails */ flags |= FORCE; break; case 'n': /* No warning popups - Obsolete */ flags |= NO_WARN; break; case 'x': /* Don't try to screenlock */ flags |= NO_XLOCK; break; case 'h': /* Do a shutdown instead of suspend */ flags |= SHUTDOWN; break; case 'd': /* Needswork */ /* Set the DISPLAY value in the environment */ if (strlen(optarg) >= MAXNAMELEN) { (void) printf(gettext("Error: " "display name is too long.\n")); return (1); } (void) strcat(display_name, optarg); if (putenv(display_name) != 0) { (void) printf(gettext("Error: " "unable to set DISPLAY " "environment variable.\n")); return (1); } break; case 't': /* Test, don't actually do any operation */ flags |= TEST; break; default: (void) printf(gettext("USAGE: suspend " "[-fnxh] [-d <display>]\n")); return (1); } } /* * The action of pressing power key and power button on a MOU-3 machine * causes suspend being invoked with SYSSUSPENDDODEFAULT * enviromental variable set - indicating the default action is machine * dependent: for MOU-3 type machine, "LowPower" mode is the default, * for all the rest, "Suspend" is the default. Existing suspend * flags works the same. */ if (getenv("SYSSUSPENDDODEFAULT")) if (is_mou3()) flags |= LOWPOWER; if ((flags & FORCE) && (flags & LOWPOWER)) flags &= ~LOWPOWER; /* * Flag "-h" overrides flag "-f". */ if ((flags & SHUTDOWN) && (flags & FORCE)) flags &= ~(FORCE | LOWPOWER); if (flags & FORCE) flags |= NO_WARN; /* * Check initally if the user has the authorizations to * do either a suspend or shutdown. pm_suspend() will also * make this test, so we could defer till then, but if we * do it now, we at least prevent a lot of unneeded setup. */ pw = getpwuid(getuid()); (void) strncpy(user, pw->pw_name, NMAX); if ((flags & (FORCE|SHUTDOWN)) && (chkauthattr(AUTHNAME_SHUTDOWN, pw->pw_name) != 1)) { (void) printf(gettext("User does not have correct " "authorizations to shutdown the machine.\n")); exit(1); } if (!(flags & SHUTDOWN) && (chkauthattr(AUTHNAME_SUSPEND, pw->pw_name) != 1)) { (void) printf(gettext("User does not have correct " "authorizations to suspend.\n")); exit(1); } /* * If we are only shutting down, there isn't much to do, just * call pm_poweroff(), and let it do all the work. */ if (flags & SHUTDOWN) { /* * pm_poweroff either powers off or exits, * so there is no return. */ if (flags & TEST) { (void) printf("TEST: This machine would have " "powered off\n"); exit(1); } else { pm_poweroff(); } /* NOTREACHED */ } /* * If XAUTHORITY environment variable is not set, try to set * one up. */ if (getenv("XAUTHORITY") == NULL) (void) putenv(get_xauthority(xauthority)); /* * In case of "suspend" being called from daemon "powerd", * signal SIGALRM is blocked so use "sigset()" instead of "signal()". */ (void) sigset(SIGALRM, alarm_handler); /* Call the "suspend" function to do the last of the work */ pm_suspend(); if (refresh_dt() == -1) { (void) printf("%s: Failed to refresh screen.\n", argv[0]); return (1); } return (0); }
/* * This entry point _should_ be the common entry to suspend. It is in * it's entirety here, but would be best moved to libpower when that * is available. */ static void pm_suspend(void) { int cprarg = AD_SUSPEND; enum adt_uadmin_fcn fcn_id = ADT_FCN; au_event_t event_id = ADT_uadmin_freeze; adt_event_data_t *event = NULL; /* event to be generated */ adt_session_data_t *ah = NULL; /* audit session handle */ /* * Does the user have permission to use this command? */ if (chkauthattr(AUTHNAME_SUSPEND, user) != 1) { (void) printf(gettext("User %s does not have correct " "authorizations to suspend this machine.\n"), user); exit(1); } if (flags & LOWPOWER) { if (bringto_lowpower() == -1) { (void) printf(gettext("LowPower Failed\n")); exit(1); } } else if (flags & TEST) { /* * Test mode, do checks as if a real suspend, but * don't actually do the suspend. */ /* Check if suspend is supported */ if (pm_check_suspend() == -1) { suspend_error(errno); } (void) printf(gettext("TEST: Suspend would have been" " performed\n")); } else { /* Check if suspend is supported */ if (pm_check_suspend() == -1) { suspend_error(errno); } /* * We are about to suspend this machine, try and * lock the screen. We don't really care if this * succeeds or not, but that we actually tried. We * also know that we have sufficient privileges to * be here, so we lock the screen now, even if * suspend actually fails. * Note that garbage is sometimes displayed, and * we don't really care about it, so we toss all * text response. * it would also be good if there were another option * instead of launcing a file, as the disk might be * spun down if we are suspending due to idle. */ if (!(flags & NO_XLOCK)) { (void) system("/usr/bin/xdg-screensaver lock " " >/dev/null 2>&1"); } /* Time to do the actual deed! */ /* * Before we actually suspend, we need to audit and * "suspend" the audit files. */ /* set up audit session and event */ if (adt_start_session(&ah, NULL, ADT_USE_PROC_DATA) == 0) { if ((event = adt_alloc_event(ah, event_id)) != NULL) { event->adt_uadmin_freeze.fcn = fcn_id; event->adt_uadmin_freeze.mdep = NULL; if (adt_put_event(event, ADT_SUCCESS, 0) != 0) { (void) fprintf(stderr, gettext( "%s: can't put audit event\n"), argvl[0]); } else { wait_for_auqueue(); } } (void) change_audit_file(); } else { (void) fprintf(stderr, gettext( "%s: can't start audit session\n"), argvl[0]); } if (uadmin(A_FREEZE, cprarg, 0) != 0) { (void) printf(gettext("Suspend Failed\n")); if (flags & FORCE) { /* * Note, that if we actually poweroff, * that the poweroff function will handle * that audit trail, and the resume * trail is effectively done. */ pm_poweroff(); } else { /* suspend_error() will exit. */ suspend_error(errno); /* * Audit the suspend failure and * reuse the event, but don't create one * if we don't already have one. */ if (event != NULL) { (void) adt_put_event(event, ADT_FAILURE, 0); } } } /* * Write the thaw event. */ if (ah != NULL) { if ((event == NULL) && ((event = adt_alloc_event(ah, ADT_uadmin_thaw)) == NULL)) { (void) fprintf(stderr, gettext( "%s: can't allocate thaw audit event\n"), argvl[0]); } else { event->adt_uadmin_thaw.fcn = fcn_id; if (adt_put_event(event, ADT_SUCCESS, 0) != 0) { (void) fprintf(stderr, gettext( "%s: can't put thaw audit event\n"), argvl[0]); } (void) adt_free_event(event); } } } if ((no_tty ? 0 : 1) && !(flags & NO_XLOCK)) { pm_do_auth(ah); } (void) adt_end_session(ah); }
/* * build_mgmt_request -- extracts the request info from the given XML doc. * * x_doc: ptr to the request XML doc * req: ptr to the request struct to be filled up. * * Return value: ISNS_RSP_SUCCESSFUL if successful or an error code. */ static int process_mgmt_request(xmlDocPtr x_doc, request_t *req, ucred_t *uc) { result_code_t ret; int op; xmlXPathContextPtr ctext = NULL; uid_t user; struct passwd pwds, *pwd; char buf_pwd[1024]; isnslog(LOG_DEBUG, "process_mgmt_request", "entered"); (void) memset(req, 0, sizeof (request_t)); /* get the operation first. */ ctext = xmlXPathNewContext(x_doc); if (ctext == NULL) { return (ERR_XML_FAILED_TO_SET_XPATH_CONTEXT); } isnslog(LOG_DEBUG, "process_mgmt_request", "xpath context succeeded"); op = get_op_id_from_doc(ctext); if (op == -1) { if (ctext) xmlXPathFreeContext(ctext); return (ERR_XML_VALID_OPERATION_NOT_FOUND); } user = ucred_getruid(uc); ret = getpwuid_r(user, &pwds, buf_pwd, sizeof (buf_pwd), &pwd); if (ret != 0) { if (ctext) xmlXPathFreeContext(ctext); return (ERR_DOOR_SERVER_DETECTED_INVALID_USER); } /* write operations are restricted. */ if ((op == delete_op) || (op == createModify_op)) { if (!chkauthattr(ISNS_ADMIN_WRITE_AUTH, pwd->pw_name)) { if (ctext) xmlXPathFreeContext(ctext); return (ERR_DOOR_SERVER_DETECTED_NOT_AUTHORIZED_USER); } } req->op_info.op = op; if (ISNS_MGMT_OPERATION_TYPE_ENABLED()) { ISNS_MGMT_OPERATION_TYPE(op); } switch (op) { case (get_op): ret = process_get_request_from_doc(ctext, req); break; case (getAssociated_op): ret = process_getAssociated_request_from_doc(ctext, req); break; case (enumerate_op): ret = process_enumerate_request_from_doc(ctext, req); break; case (delete_op): ret = process_delete_request_from_doc(ctext, req); break; case (createModify_op): ret = process_createModify_request_from_doc(ctext, req); break; default: ret = ERR_XML_VALID_OPERATION_NOT_FOUND; } if (ctext) xmlXPathFreeContext(ctext); return (ret); }
static void main_loop(char *devname, boolean_t cttyflag) { int fd, fb, i; char *user = NULL; /* authorized user */ char *pass; /* password from user */ char *cpass; /* crypted password */ struct spwd spwd; struct spwd *lshpw; /* local shadow */ char shadow[NSS_BUFLEN_SHADOW]; FILE *sysmsgfd; for (i = 0; i < 3; i++) (void) close(i); if (cttyflag == B_FALSE) { if (setsid() == -1) exit(EXIT_FAILURE); } if ((fd = open(devname, O_RDWR)) < 0) exit(EXIT_FAILURE); /* * In system maintenance mode, all virtual console instances * of the svc:/system/console-login service are not available * any more, and only the system console is available. So here * we always switch to the system console in case at the moment * the active console isn't it. */ (void) ioctl(fd, VT_ACTIVATE, 1); if (fd != 0) (void) dup2(fd, STDIN_FILENO); if (fd != 1) (void) dup2(fd, STDOUT_FILENO); if (fd != 2) (void) dup2(fd, STDERR_FILENO); if (fd > 2) (void) close(fd); /* Stop progress bar and reset console mode to text */ if ((fb = open("/dev/fb", O_RDONLY)) >= 0) { (void) ioctl(fb, KDSETMODE, KD_RESETTEXT); (void) close(fb); } sysmsgfd = fopen("/dev/sysmsg", "w"); sanitize_tty(fileno(stdin)); for (;;) { do { (void) printf("\nEnter user name for system " "maintenance (control-d to bypass): "); user = sulogin_getinput(devname, ECHOON); if (user == NULL) { /* signal other children to exit */ (void) sigsend(P_PID, masterpid, SIGUSR1); /* ^D, so straight to default init state */ exit(EXIT_FAILURE); } } while (user[0] == '\0'); (void) printf("Enter %s password (control-d to bypass): ", user); if ((pass = sulogin_getinput(devname, ECHOOFF)) == NULL) { /* signal other children to exit */ (void) sigsend(P_PID, masterpid, SIGUSR1); /* ^D, so straight to default init state */ free(user); exit(EXIT_FAILURE); } lshpw = getspnam_r(user, &spwd, shadow, sizeof (shadow)); if (lshpw == NULL) { /* * the user entered doesn't exist, too bad. */ goto sorry; } /* * There is a special case error to catch here: * If the password is hashed with an algorithm * other than the old unix crypt the call to crypt(3c) * could fail if /usr is corrupt or not available * since by default /etc/security/crypt.conf will * have the crypt_ modules located under /usr/lib. * Or it could happen if /etc/security/crypt.conf * is corrupted. * * If this happens crypt(3c) will return NULL and * set errno to ELIBACC for the former condition or * EINVAL for the latter, in this case we bypass * authentication and just verify that the user is * authorized. */ errno = 0; cpass = crypt(pass, lshpw->sp_pwdp); if (((cpass == NULL) && (lshpw->sp_pwdp[0] == '$')) && ((errno == ELIBACC) || (errno == EINVAL))) { goto checkauth; } else if ((cpass == NULL) || (strcmp(cpass, lshpw->sp_pwdp) != 0)) { goto sorry; } checkauth: /* * There is a special case error here as well. * If /etc/user_attr is corrupt, getusernam("root") * returns NULL. * In this case, we just give access because this is similar * to the case of root not existing in /etc/passwd. */ if ((getusernam("root") != NULL) && (chkauthattr(MAINTENANCE_AUTH, user) != 1)) { goto sorry; } (void) fprintf(sysmsgfd, "\nsingle-user privilege " "assigned to %s on %s.\n", user, devname); (void) sigsend(P_PID, masterpid, SIGUSR1); (void) wait(NULL); free(user); free(pass); single(su, devname); /* single never returns */ sorry: (void) printf("\nLogin incorrect or user %s not authorized\n", user); free(user); free(pass); (void) sleep(sleeptime); } }
/* * Verifies the provided list of authorizations are all valid. * * Returns NULL if all authorization names are valid. * Otherwise, returns the invalid authorization name * */ static const char * check_auth(const char *auths) { char *authname; authattr_t *result; char *tmp; struct passwd *pw; int have_grant = 0; tmp = strdup(auths); if (tmp == NULL) { errmsg(M_NOSPACE); exit(EX_FAILURE); } authname = strtok(tmp, AUTH_SEP); pw = getpwuid(getuid()); if (pw == NULL) { return (authname); } while (authname != NULL) { char *suffix; char *authtoks; /* Check if user has been granted this authorization */ if (!chkauthattr(authname, pw->pw_name)) return (authname); /* Remove named object after slash */ if ((suffix = index(authname, KV_OBJECTCHAR)) != NULL) *suffix = '\0'; /* Find the suffix */ if ((suffix = rindex(authname, '.')) == NULL) return (authname); /* Check for existence in auth_attr */ suffix++; if (strcmp(suffix, KV_WILDCARD)) { /* Not a wildcard */ result = getauthnam(authname); if (result == NULL) { /* can't find the auth */ free_authattr(result); return (authname); } free_authattr(result); } /* Check if user can delegate this authorization */ if (strcmp(suffix, "grant")) { /* Not a grant option */ authtoks = malloc(strlen(authname) + sizeof ("grant")); strcpy(authtoks, authname); have_grant = 0; while ((suffix = rindex(authtoks, '.')) && !have_grant) { strcpy(suffix, ".grant"); if (chkauthattr(authtoks, pw->pw_name)) have_grant = 1; else *suffix = '\0'; } if (!have_grant) return (authname); } authname = strtok(NULL, AUTH_SEP); } free(tmp); return (NULL); }