int main(int argc, char **argv) { int ret = -1; char path[PATH_MAX]; test_init(argc, argv); if (mount_and_add(cgname, "test") < 0) return -1; sprintf(path, "%s/%s/test", dirname, cgname); if (chownmod(path, O_DIRECTORY) < 0) goto out_umount; sprintf(path, "%s/%s/test/notify_on_release", dirname, cgname); if (chownmod(path, O_RDWR) < 0) goto out_umount; sprintf(path, "%s/%s/test/cgroup.procs", dirname, cgname); if (chownmod(path, O_RDWR) < 0) goto out_umount; test_daemon(); test_waitsig(); sprintf(path, "%s/%s/test", dirname, cgname); if (checkperms(path) < 0) goto out_umount; sprintf(path, "%s/%s/test/notify_on_release", dirname, cgname); if (checkperms(path) < 0) goto out_umount; sprintf(path, "%s/%s/test/cgroup.procs", dirname, cgname); if (checkperms(path) < 0) goto out_umount; pass(); ret = 0; out_umount: sprintf(path, "%s/%s/test", dirname, cgname); rmdir(path); sprintf(path, "%s/%s", dirname, cgname); umount(path); rmdir(path); rmdir(dirname); return ret; }
void s_print_request(char *m, MESG *md) { extern char *Local_System; char *file; char *idno; char *path; char *req_file; char *req_id = 0; RSTATUS *rp; REQUEST *r; SECURE *s; struct passwd *pw; short err; short status; off_t size; uid_t org_uid; gid_t org_gid; #ifdef LP_USE_PAPI_ATTR struct stat tmpBuf; char tmpName[BUFSIZ]; #endif (void) getmessage(m, S_PRINT_REQUEST, &file); syslog(LOG_DEBUG, "s_print_request(%s)", (file ? file : "NULL")); /* * "NewRequest" points to a request that's not yet in the * request list but is to be considered with the rest of the * requests (e.g. calculating # of requests awaiting a form). */ if ((rp = NewRequest = new_rstatus(NULL, NULL)) == NULL) status = MNOMEM; else { req_file = reqpath(file, &idno); path = makepath(Lp_Tmp, req_file, (char *)0); (void) chownmod(path, Lp_Uid, Lp_Gid, 0644); Free(path); if (!(r = Getrequest(req_file))) status = MNOOPEN; else { rp->req_file = Strdup(req_file); freerequest(rp->request); rp->request = r; rp->request->outcome = 0; rp->secure->uid = md->uid; rp->secure->gid = md->gid; if (md->slabel != NULL) rp->secure->slabel = Strdup(md->slabel); pw = getpwuid(md->uid); endpwent(); if (pw && pw->pw_name && *pw->pw_name) rp->secure->user = Strdup(pw->pw_name); else { rp->secure->user = Strdup(BIGGEST_NUMBER_S); (void) sprintf(rp->secure->user, "%u", md->uid); } if ((rp->request->actions & ACT_SPECIAL) == ACT_HOLD) rp->request->outcome |= RS_HELD; if ((rp->request->actions & ACT_SPECIAL) == ACT_RESUME) rp->request->outcome &= ~RS_HELD; if ((rp->request->actions & ACT_SPECIAL) == ACT_IMMEDIATE) { if (!md->admin) { status = MNOPERM; goto Return; } rp->request->outcome |= RS_IMMEDIATE; } size = chfiles(rp->request->file_list, Lp_Uid, Lp_Gid); if (size < 0) { /* * at this point, chfiles() may have * failed because the file may live on * an NFS mounted filesystem, under * a directory of mode 700. such a * directory isn't accessible even by * root, according to the NFS protocol * (i.e. the Stat() in chfiles() failed). * this most commonly happens via the * automounter, and rlogin. thus we * change our euid/egid to that of the * user, and try again. if *this* fails, * then the file must really be * inaccessible. */ org_uid = geteuid(); org_gid = getegid(); if (setegid(md->gid) != 0) { status = MUNKNOWN; goto Return; } if (seteuid(md->uid) != 0) { setgid(org_gid); status = MUNKNOWN; goto Return; } size = chfiles(rp->request->file_list, Lp_Uid, Lp_Gid); if (seteuid(org_uid) != 0) { /* should never happen */ note("s_print_request(): "); note("seteuid back to uid=%d " "failed!!\n", org_uid); size = -1; } if (setegid(org_gid) != 0) { /* should never happen */ note("s_print_request(): "); note("setegid back to uid=%d " "failed!!\n", org_uid); size = -1; } if (size < 0) { status = MUNKNOWN; goto Return; } } if (!(rp->request->outcome & RS_HELD) && size == 0) { status = MNOPERM; goto Return; } rp->secure->size = size; (void) time(&rp->secure->date); rp->secure->req_id = NULL; if (!rp->request->title) { if (strlen(*rp->request->file_list) < (size_t)24) rp->request->title = Strdup(*rp->request->file_list); else { char *r; if (r = strrchr( *rp->request->file_list, '/')) r++; else r = *rp->request->file_list; rp->request->title = malloc(25); sprintf(rp->request->title, "%-.24s", r); } } if ((err = validate_request(rp, &req_id, 0)) != MOK) status = err; else { /* * "req_id" will be supplied if this is from a * remote system. */ if (rp->secure->req_id == NULL) { req_id = makestr(req_id, "-", idno, (char *)0); rp->secure->req_id = req_id; } else req_id = rp->secure->req_id; #ifdef LP_USE_PAPI_ATTR /* * Check if the PAPI job attribute file * exists, if it does change the * permissions and ownership of the file. * This file is created when print jobs * are submitted via the PAPI interface, * the file pathname of this file is * passed to the slow-filters and printer * interface script as an environment * variable when they are executed */ snprintf(tmpName, sizeof (tmpName), "%s-%s", idno, LP_PAPIATTRNAME); path = makepath(Lp_Temp, tmpName, (char *)0); if (stat(path, &tmpBuf) == 0) { syslog(LOG_DEBUG, "s_print_request: "\ "attribute file ='%s'", path); /* * IPP job attribute file exists * for this job so change * permissions and ownership of * the file */ (void) chownmod(path, Lp_Uid, Lp_Gid, 0644); Free(path); } else { syslog(LOG_DEBUG, "s_print_request: "\ "no attribute file"); } #endif /* * fix for bugid 1103890. * use Putsecure instead. */ if ((Putsecure(req_file, rp->secure) == -1) || (putrequest(req_file, rp->request) == -1)) status = MNOMEM; else { status = MOK; insertr(rp); NewRequest = 0; if (rp->slow) schedule(EV_SLOWF, rp); else schedule(EV_INTERF, rp->printer); del_flt_act(md, FLT_FILES); } } } } Return: NewRequest = 0; Free(req_file); Free(idno); if (status != MOK && rp) { rmfiles(rp, 0); free_rstatus(rp); } mputm(md, R_PRINT_REQUEST, status, NB(req_id), chkprinter_result); }
void s_end_change_request(char *m, MESG *md) { char *req_id; RSTATUS *rp; off_t size; off_t osize; short err; short status; REQUEST *r = 0; REQUEST oldr; int call_schedule = 0; int move_ok = 0; char *path; char tmpName[BUFSIZ]; struct stat tmpBuf; (void) getmessage(m, S_END_CHANGE_REQUEST, &req_id); syslog(LOG_DEBUG, "s_end_change_request(%s)", (req_id ? req_id : "NULL")); if (!(rp = request_by_id(req_id))) status = MUNKNOWN; else if ((md->admin == 0) && (is_system_labeled()) && (md->slabel != NULL) && (rp->secure->slabel != NULL) && (!STREQU(md->slabel, rp->secure->slabel))) status = MUNKNOWN; else if (!(rp->request->outcome & RS_CHANGING)) status = MNOSTART; else { path = makepath(Lp_Tmp, rp->req_file, (char *)0); (void) chownmod(path, Lp_Uid, Lp_Gid, 0644); Free(path); #ifdef LP_USE_PAPI_ATTR /* * Check if the PAPI job attribute file exists, * if it does change the permission and the ownership * of the file to be "Lp_Uid". */ snprintf(tmpName, sizeof (tmpName), "%s-%s", strtok(strdup(rp->req_file), "-"), LP_PAPIATTRNAME); path = makepath(Lp_Tmp, tmpName, (char *)0); if (stat(path, &tmpBuf) == 0) { syslog(LOG_DEBUG, "s_end_change_request: attribute file ='%s'", path); /* * IPP job attribute file exists for this job so * change permissions and ownership of the file */ (void) chownmod(path, Lp_Uid, Lp_Gid, 0644); Free(path); } else { syslog(LOG_DEBUG, "s_end_change_request: no attribute file"); } #endif rp->request->outcome &= ~(RS_CHANGING); del_flt_act(md, FLT_CHANGE); /* * The RS_CHANGING bit may have been the only thing * preventing this request from filtering or printing, * so regardless of what happens below, * we must check to see if the request can proceed. */ call_schedule = 1; if (!(r = Getrequest(rp->req_file))) status = MNOOPEN; else { oldr = *(rp->request); *(rp->request) = *r; move_ok = STREQU(oldr.destination, r->destination); /* * Preserve the current request status! */ rp->request->outcome = oldr.outcome; /* * Here's an example of the dangers one meets * when public flags are used for private * purposes. ".actions" (indeed, anything in the * REQUEST structure) is set by the person * changing the job. However, lpsched uses * ".actions" as place to indicate that a job * came from a remote system and we must send * back job completion--this is a strictly * private flag that we must preserve. */ rp->request->actions |= (oldr.actions & ACT_NOTIFY); if ((rp->request->actions & ACT_SPECIAL) == ACT_HOLD) { rp->request->outcome |= RS_HELD; /* * To be here means either the user owns * the request or he or she is the * administrator. Since we don't want to * set the RS_ADMINHELD flag if the user * is the administrator, the following * compare will work. */ if (md->uid != rp->secure->uid) rp->request->outcome |= RS_ADMINHELD; } if ((rp->request->actions & ACT_SPECIAL) == ACT_RESUME) { if ((rp->request->outcome & RS_ADMINHELD) && !md->admin) { status = MNOPERM; goto Return; } rp->request->outcome &= ~(RS_ADMINHELD|RS_HELD); } if ((rp->request->actions & ACT_SPECIAL) == ACT_IMMEDIATE) { if (!md->admin) { status = MNOPERM; goto Return; } rp->request->outcome |= RS_IMMEDIATE; } size = chfiles(rp->request->file_list, Lp_Uid, Lp_Gid); if (size < 0) { status = MUNKNOWN; goto Return; } if (!(rp->request->outcome & RS_HELD) && size == 0) { status = MNOPERM; goto Return; } osize = rp->secure->size; rp->secure->size = size; if (move_ok == 0) { char *dest = strdup(r->destination); if ((status = mv_file(rp, dest)) == MOK) rp->secure->size = osize; free(dest); } else if ((err = validate_request(rp, (char **)0, move_ok)) != MOK) { status = err; rp->secure->size = osize; } else { status = MOK; if ((rp->request->outcome & RS_IMMEDIATE) || (rp->request->priority != oldr.priority)) { remover(rp); insertr(rp); } freerequest(&oldr); (void) putrequest(rp->req_file, rp->request); /* * fix for bugid 1103890. * use Putsecure instead. */ (void) Putsecure(rp->req_file, rp->secure); } } } Return: if (status != MOK && rp) { if (r) { freerequest(r); *(rp->request) = oldr; } if (status != MNOSTART) (void) putrequest(rp->req_file, rp->request); } if (call_schedule) maybe_schedule(rp); mputm(md, R_END_CHANGE_REQUEST, status, chkprinter_result); }