static DBusMessage *unregister_agent(DBusConnection *conn, DBusMessage *msg, void *data) { const char *path, *sender; if (!agent) return agent_does_not_exist(msg); if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID)) return invalid_args(msg); if (strcmp(agent->path, path) != 0) return agent_does_not_exist(msg); sender = dbus_message_get_sender(msg); if (strcmp(agent->bus_name, sender) != 0) return not_authorized(msg); g_dbus_remove_watch(conn, agent->watch_id); agent_free(agent); agent = NULL; DBG("Agent unregistered"); return dbus_message_new_method_return(msg); }
static DBusMessage *cancel_authorization(DBusConnection *conn, DBusMessage *msg, void *data) { DBusMessage *reply; struct service_adapter *serv_adapter = data; struct pending_auth *auth; const gchar *sender; bdaddr_t src; sender = dbus_message_get_sender(msg); auth = find_pending_by_sender(serv_adapter, sender); if (auth == NULL) return does_not_exist(msg); if (serv_adapter->adapter) adapter_get_address(serv_adapter->adapter, &src); else bacpy(&src, BDADDR_ANY); btd_cancel_authorization(&src, &auth->dst); reply = not_authorized(auth->msg); dbus_message_unref(auth->msg); g_dbus_send_message(auth->conn, reply); dbus_connection_unref(auth->conn); serv_adapter->pending_list = g_slist_remove(serv_adapter->pending_list, auth); g_free(auth); auth = next_pending(serv_adapter); if (auth == NULL) goto done; if (serv_adapter->adapter) adapter_get_address(serv_adapter->adapter, &src); else bacpy(&src, BDADDR_ANY); btd_request_authorization(&src, &auth->dst, auth->uuid, auth_cb, serv_adapter); done: return dbus_message_new_method_return(msg); }
static DBusMessage *transfer_cancel(DBusConnection *connection, DBusMessage *msg, void *user_data) { struct obex_session *os = user_data; const char *sender; if (!os) return invalid_args(msg); sender = dbus_message_get_sender(msg); if (strcmp(agent->bus_name, sender) != 0) return not_authorized(msg); os->aborted = TRUE; return dbus_message_new_method_return(msg); }
static void auth_cb(DBusError *derr, void *user_data) { struct service_adapter *serv_adapter = user_data; DBusMessage *reply; struct pending_auth *auth; bdaddr_t src; auth = next_pending(serv_adapter); if (auth == NULL) { info("Authorization cancelled: Client exited"); return; } if (derr) { error("Access denied: %s", derr->message); reply = not_authorized(auth->msg); dbus_message_unref(auth->msg); g_dbus_send_message(auth->conn, reply); goto done; } g_dbus_send_reply(auth->conn, auth->msg, DBUS_TYPE_INVALID); done: dbus_connection_unref(auth->conn); serv_adapter->pending_list = g_slist_remove(serv_adapter->pending_list, auth); g_free(auth); auth = next_pending(serv_adapter); if (auth == NULL) return; if (serv_adapter->adapter) adapter_get_address(serv_adapter->adapter, &src); else bacpy(&src, BDADDR_ANY); btd_request_authorization(&src, &auth->dst, auth->uuid, auth_cb, serv_adapter); }
int main(int argc, char **argv) { char crontab[11 + LOGIN_NAME_MAX] = "crontabs/";/* partial pathname */ struct passwd *pwent; /* passwd struct */ int ch; /* option character */ FILE *tab, *tmp = NULL; /* output/input files */ int action = CREATE; #ifdef __WATCOMC__ nid_t nid = 0, qnx_strtonid(); /* server node */ pid_t server; int local = 0; argv0 = basename(argv[0]); pwent = getpwuid(getuid()); umask(066); while ((ch = getopt(argc, argv, "d:en:lLru:")) != EOF) { switch (ch) { case 'L': nid = getnid(); local = !local; break; case 'n': nid = qnx_strtonid(optarg); local = !local; break; #else void * server = NULL; int fd; /* shm_open file handle */ int euid, egid; argv0 = basename(argv[0]); pwent = getpwuid(getuid()); umask(066); while ((ch = getopt(argc, argv, "d:elru:")) != EOF) { switch (ch) { #endif case 'd': crondir = optarg; break; case 'e': action = EDIT; break; case 'l': if (action == REMOVE) fatal_message("conflict: -r/-l"); action = LIST; break; case 'r': if (action == LIST) { fatal_message("conflict: -r/-l"); } action = REMOVE; break; case 'u': /* get name and uid/gid for user */ if ((pwent = getpwnam(optarg)) == 0) { long id = strtol(optarg, (char **) &pwent, 10); if (*(char *) pwent != 0) { fatal_message("%s %s", "invalid user", optarg); } if ((pwent = getpwuid(id)) == 0) { fatal_message("%s %s", "unknown user", optarg); } } break; default: exit(EXIT_FAILURE); } } /* make sure we're allowed to do anything with this crontab */ if (getuid() != pwent->pw_uid && getuid() != 0) { fatal_message("access denied to crontab for %s", pwent->pw_name); } /* Locate the server */ #ifdef __WATCOMC__ switch (nid) { case 0: if ((server = qnx_name_locate(0, cronsrv + 1, 0, 0)) != -1) { nid = getnid(); local++; break; } /* fallthru */ default: server = qnx_name_locate(nid, cronsrv + local, 0, 0); } if (server == -1) fprintf(stderr, "warning: cron has not been started\n"); if (local) { crondir = malloc(strlen(optarg = crondir) + 8); sprintf(crondir, "%s.%ld", optarg, nid); } #else /* check if cron server is running. */ if ((fd = shm_open(SHM_CRON, O_RDONLY, S_IRWXU )) == -1) { fprintf(stderr, "warning: cron has not been started\n"); } else if(MAP_FAILED == (server = mmap(0, sizeof(pid_t), PROT_READ, MAP_SHARED, fd, 0))) { fatal_message("mmapp: %s", strerror(errno)); } if(server && kill(*(pid_t *)server, 0) == -1) { fatal_message("cron stopped abnormally"); } close(fd); #endif strcat(crontab, pwent->pw_name); if (optind == argc) { if (action == CREATE || action == EDIT) { char work[] = "/tmp/cronXXXX"; mktemp(work); if (action == CREATE) { /* read replacement crontab from stdin */ tmp = fopen(work, "w+"); while ((ch = getchar()) != EOF) fputc(ch, tmp); } else { char *editor = getenv("EDITOR"); int status; if (editor == NULL) editor = "vi"; if (chdir(crondir) == -1) fatal_message("%s: %s", crondir, strerror(errno)); if ((tab = fopen(crontab, "r")) == 0 && errno != ENOENT) { fatal_message("%s/%s: %s", crondir, pwent->pw_name, strerror(errno)); } egid = getegid(); euid = geteuid(); setegid(getgid()); seteuid(getuid()); tmp = fopen(work, "w+"); if (tab) { while ((ch = fgetc(tab)) != EOF) fputc(ch, tmp); fflush(tmp); fclose(tab); } if ((status = spawnlp(P_WAIT, editor, editor, work, 0))) { remove(work); fatal_message(status == -1 ? "unable to start %s" : "%s exited %d", editor, status); } setegid(egid); seteuid(euid); } remove(work); rewind(tmp); } } else if (optind == argc - 1 && action == CREATE) { /* copy file onto crontab */ if (access(argv[optind], R_OK) != 0 || (tmp = fopen(argv[optind], "r")) == 0) { fatal_message("%s: %s", argv[optind], strerror(errno)); } } else { fatal_message("too many arguments"); } if(chdir(crondir) != 0) fatal_message("crontab %s: %s", strerror(errno), crondir); if (not_authorized(pwent->pw_name) && pwent->pw_uid != 0) { fprintf(stderr, "warning: no permission for cron: %s\n", pwent->pw_name); } if (action == LIST) { if ((tab = fopen(crontab, "r")) == 0) { if(errno == ENOENT) fatal_message("no crontab for %s", pwent->pw_name); fatal_message("%s: %s", pwent->pw_name, strerror(errno)); } else { while ((ch = fgetc(tab)) != EOF) putchar(ch); fclose(tab); } } else { /* drop and store euid/egid, use uid/gid */ egid = getegid(); euid = geteuid(); setegid(getgid()); seteuid(getuid()); chmod(crontab, S_IRWXU); /* -rw---- */ if (action == REMOVE) { if (remove(crontab) == -1 && errno != ENOENT) { fatal_message("%s: %s", strerror(errno), crontab); } } else if (action == CREATE || action == EDIT) { if ((tab = fopen(crontab, "w")) == NULL) { fatal_message("%s: %s", strerror(errno), crontab); } while ((ch = fgetc(tmp)) != EOF) fputc(ch, tab); fflush(tab); /* Changing write permissions later! */ fchown(fileno(tab), pwent->pw_uid, pwent->pw_gid); fchmod(fileno(tab), S_IRUSR); /* -r----- */ fclose(tab); fclose(tmp); } /* restore euid/egid for kill */ setegid(egid); seteuid(euid); /* Notify server */ #ifdef __WATCOMC__ if (server != -1 && Send(server, pwent->pw_name, 0, strlen(pwent->pw_name) + 1, 0) < 0) { #else if(server && kill(*(pid_t *)server, SIGUSR1) == -1) { #endif fatal_message("inform cron about update: %s", strerror(errno)); } } return EXIT_SUCCESS; }
static DBusMessage *request_authorization(DBusConnection *conn, DBusMessage *msg, void *data) { struct record_data *user_record; struct service_adapter *serv_adapter = data; sdp_record_t *record; sdp_list_t *services; const char *sender; dbus_uint32_t handle; const char *address; struct pending_auth *auth; char uuid_str[MAX_LEN_UUID_STR]; uuid_t *uuid, *uuid128; bdaddr_t src; if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &address, DBUS_TYPE_UINT32, &handle, DBUS_TYPE_INVALID) == FALSE) return NULL; sender = dbus_message_get_sender(msg); if (find_pending_by_sender(serv_adapter, sender)) return failed(msg); user_record = find_record(serv_adapter, handle, sender); if (!user_record) { user_record = find_record(serv_adapter_any, handle, sender); if (!user_record) return not_authorized(msg); } record = sdp_record_find(user_record->handle); if (sdp_get_service_classes(record, &services) < 0) { sdp_record_free(record); return not_authorized(msg); } if (services == NULL) return not_authorized(msg); uuid = services->data; uuid128 = sdp_uuid_to_uuid128(uuid); sdp_list_free(services, bt_free); if (sdp_uuid2strn(uuid128, uuid_str, MAX_LEN_UUID_STR) < 0) { bt_free(uuid128); return not_authorized(msg); } bt_free(uuid128); auth = g_new0(struct pending_auth, 1); auth->msg = dbus_message_ref(msg); auth->conn = dbus_connection_ref(connection); auth->sender = user_record->sender; memcpy(auth->uuid, uuid_str, MAX_LEN_UUID_STR); str2ba(address, &auth->dst); serv_adapter->pending_list = g_slist_append(serv_adapter->pending_list, auth); auth = next_pending(serv_adapter); if (auth == NULL) return does_not_exist(msg); if (serv_adapter->adapter) adapter_get_address(serv_adapter->adapter, &src); else bacpy(&src, BDADDR_ANY); if (btd_request_authorization(&src, &auth->dst, auth->uuid, auth_cb, serv_adapter) < 0) { serv_adapter->pending_list = g_slist_remove(serv_adapter->pending_list, auth); g_free(auth); return not_authorized(msg); } return NULL; }