void job_destroy(job_t *job) { char *name = NULL; jobfile_t *cf; if (job == NULL) return; syslog(LOG_DEBUG, "job_destroy(%d, %s, %s)", job->job_id, job->job_printer, job->job_server); if (chdir(job->job_spool_dir) < 0) return; (void) list_iterate((void *)job->job_df_list, (VFUNC_T)_job_unlink_data_file); /* lose privilege temporarily */ (void) seteuid(get_user_id(job->job_user)); if ((cf = job->job_cf) != NULL) { for (name = cf->jf_data; name != NULL; name = strchr(name, '\n')) { if (name[0] == '\n') name++; if (name[0] == CF_UNLINK) { struct stat st; char *path = strcdup(&name[1], '\n'), *p; if (stat(path, &st) < 0) { free(path); continue; } if (st.st_uid == getuid()) { (void) unlink(path); free(path); continue; } p = strdup(path); if ((p = strrchr(p, '/')) != NULL) *++p = NULL; if (access(p, W_OK) == 0) (void) unlink(path); free(path); } } } (void) seteuid(0); /* get back privilege */ (void) unlink(cf->jf_src_path); (void) _job_unlink_data_file(cf); job_free(job); }
int proc_update_privileges(int uid, int gid) { #ifdef HAVE_SETGROUPS /* Drop supplementary groups. */ if (uid != getuid() || gid != getgid()) { if (setgroups(0, NULL) < 0) { log_server_warning("Failed to drop supplementary groups" " for uid '%d' (%s).\n", getuid(), strerror(errno)); } } #endif /* Watch uid/gid. */ if (gid != getgid()) { log_server_info("Changing group id to '%d'.\n", gid); if (setregid(gid, gid) < 0) { log_server_error("Failed to change gid to '%d'.\n", gid); } } if (uid != getuid()) { log_server_info("Changing user id to '%d'.\n", uid); if (setreuid(uid, uid) < 0) { log_server_error("Failed to change uid to '%d'.\n", uid); } } /* Check storage writeability. */ int ret = KNOT_EOK; char *lfile = strcdup(conf()->storage, "/knot.lock"); assert(lfile != NULL); FILE* fp = fopen(lfile, "w"); if (fp == NULL) { log_server_warning("Storage directory '%s' is not writeable.\n", conf()->storage); ret = KNOT_EACCES; } else { fclose(fp); unlink(lfile); } free(lfile); return ret; }
char* pid_filename() { rcu_read_lock(); /* Read configuration. */ char* ret = NULL; if (conf()) { if (conf()->pidfile != NULL) ret = strdup(conf()->pidfile); else if (conf()->rundir != NULL) ret = strcdup(conf()->rundir, "/knot.pid"); } rcu_read_unlock(); return ret; }
static int get_job_from_cfile(jobfile_t *file, char *cFile, char *xFile, job_t *tmp) { jobfile_t *file1; int n_cnt; char *p, *cfp; /* map in the control data */ if ((file->jf_size = map_in_file(cFile, &file->jf_data, 0)) <= 0) { syslog(LOG_INFO, "could not read control file (%s): %m, " "canceling %d destined for %s:%s", (file->jf_spl_path ? file->jf_spl_path:"NULL"), tmp->job_id, (tmp->job_server ? tmp->job_server : "NULL"), (tmp->job_printer ? tmp->job_printer : "NULL")); return (0); } file->jf_mmapped = 1; tmp->job_cf = file; /* look for usr, host, & data files */ /* * Bugid 4137904 - "File Name" can be * anywhere in control file. * Bugid 4179341 - "File Name" can be missing * in control file. * Keep a separate pointer to the control file. * When a CF_UNLINK entry is found use the second * pointer to search for a corresponding 'N' entry. * The behavior is to associate the first CF_UNLINK * entry with the first 'N' entry and so on. * Note: n_cnt is only used to determine if we * should test for 'N' at the beginning of * the file. */ cfp = file->jf_data; n_cnt = 0; for (p = file->jf_data - 1; p != NULL; p = strchr(p, '\n')) { switch (*(++p)) { case CF_USER: tmp->job_user = strcdup(++p, '\n'); break; case CF_HOST: tmp->job_host = strcdup(++p, '\n'); break; case CF_UNLINK: if ((file1 = calloc(1, sizeof (*file))) == NULL) { syslog(LOG_DEBUG, "cf_unlink: calloc() failed"); munmap(file->jf_data, file->jf_size); file->jf_mmapped = 0; return (0); } file1->jf_src_path = strdup(xFile); file1->jf_spl_path = strcdup(++p, '\n'); file1->jf_size = file_size(file1->jf_spl_path); if (cfp != NULL) { /* * Beginning of file. Check for first * character == 'N' */ if ((n_cnt == 0) && (*cfp == 'N')) { cfp++; n_cnt++; } else { cfp = strstr(cfp, "\nN"); if (cfp != NULL) { cfp += 2; n_cnt++; } } if (cfp != NULL) { file1->jf_name = strcdup(cfp, '\n'); /* * Move cfp to end of line or * set to NULL if end of file. */ cfp = strchr(cfp, '\n'); } } tmp->job_df_list = (jobfile_t **)list_append((void **) tmp->job_df_list, (void *)file1); break; } } if (tmp->job_df_list == NULL) { munmap(file->jf_data, file->jf_size); file->jf_mmapped = 0; return (0); } return (1); }
int proc_update_privileges(int uid, int gid) { #ifdef HAVE_SETGROUPS /* Drop supplementary groups. */ if ((uid_t)uid != getuid() || (gid_t)gid != getgid()) { if (setgroups(0, NULL) < 0) { log_server_warning("Failed to drop supplementary groups" " for uid '%d' (%s).\n", getuid(), strerror(errno)); } # ifdef HAVE_INITGROUPS struct passwd *pw; if ((pw = getpwuid(uid)) == NULL) { log_server_warning("Failed to get passwd entry" " for uid '%d' (%s).\n", uid, strerror(errno)); } else { if (initgroups(pw->pw_name, gid) < 0) { log_server_warning("Failed to set supplementary groups" " for uid '%d' (%s).\n", uid, strerror(errno)); } } # endif /* HAVE_INITGROUPS */ } #endif /* HAVE_SETGROUPS */ /* Watch uid/gid. */ if ((gid_t)gid != getgid()) { log_server_info("Changing group id to '%d'.\n", gid); if (setregid(gid, gid) < 0) { log_server_error("Failed to change gid to '%d'.\n", gid); } } if ((uid_t)uid != getuid()) { log_server_info("Changing user id to '%d'.\n", uid); if (setreuid(uid, uid) < 0) { log_server_error("Failed to change uid to '%d'.\n", uid); } } /* Check storage writeability. */ int ret = KNOT_EOK; const bool sorted = false; hattrie_iter_t *z_iter = hattrie_iter_begin(conf()->zones, sorted); if (z_iter == NULL) { return KNOT_ERROR; } for (; !hattrie_iter_finished(z_iter); hattrie_iter_next(z_iter)) { conf_zone_t *zone = (conf_zone_t *)*hattrie_iter_val(z_iter); char *lfile = strcdup(zone->storage, "/knot.lock"); assert(lfile != NULL); FILE* fp = fopen(lfile, "w"); if (fp == NULL) { log_server_warning("Storage directory '%s' is not " "writeable.\n", zone->storage); ret = KNOT_EACCES; } else { fclose(fp); unlink(lfile); } free(lfile); if (ret != KNOT_EOK) { break; } } hattrie_iter_free(z_iter); return ret; }