1*9781SMoriah.Waterland@Sun.COM /*
2*9781SMoriah.Waterland@Sun.COM * CDDL HEADER START
3*9781SMoriah.Waterland@Sun.COM *
4*9781SMoriah.Waterland@Sun.COM * The contents of this file are subject to the terms of the
5*9781SMoriah.Waterland@Sun.COM * Common Development and Distribution License (the "License").
6*9781SMoriah.Waterland@Sun.COM * You may not use this file except in compliance with the License.
7*9781SMoriah.Waterland@Sun.COM *
8*9781SMoriah.Waterland@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*9781SMoriah.Waterland@Sun.COM * or http://www.opensolaris.org/os/licensing.
10*9781SMoriah.Waterland@Sun.COM * See the License for the specific language governing permissions
11*9781SMoriah.Waterland@Sun.COM * and limitations under the License.
12*9781SMoriah.Waterland@Sun.COM *
13*9781SMoriah.Waterland@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
14*9781SMoriah.Waterland@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*9781SMoriah.Waterland@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
16*9781SMoriah.Waterland@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
17*9781SMoriah.Waterland@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
18*9781SMoriah.Waterland@Sun.COM *
19*9781SMoriah.Waterland@Sun.COM * CDDL HEADER END
20*9781SMoriah.Waterland@Sun.COM */
21*9781SMoriah.Waterland@Sun.COM
22*9781SMoriah.Waterland@Sun.COM /*
23*9781SMoriah.Waterland@Sun.COM * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24*9781SMoriah.Waterland@Sun.COM * Use is subject to license terms.
25*9781SMoriah.Waterland@Sun.COM */
26*9781SMoriah.Waterland@Sun.COM
27*9781SMoriah.Waterland@Sun.COM /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28*9781SMoriah.Waterland@Sun.COM /* All Rights Reserved */
29*9781SMoriah.Waterland@Sun.COM
30*9781SMoriah.Waterland@Sun.COM
31*9781SMoriah.Waterland@Sun.COM #include <stdio.h>
32*9781SMoriah.Waterland@Sun.COM #include <stdlib.h>
33*9781SMoriah.Waterland@Sun.COM #include <sys/wait.h>
34*9781SMoriah.Waterland@Sun.COM #include <unistd.h>
35*9781SMoriah.Waterland@Sun.COM #include <string.h>
36*9781SMoriah.Waterland@Sun.COM #include <fcntl.h> /* creat() declaration */
37*9781SMoriah.Waterland@Sun.COM #include <sys/types.h>
38*9781SMoriah.Waterland@Sun.COM #include <sys/stat.h>
39*9781SMoriah.Waterland@Sun.COM #include <pwd.h>
40*9781SMoriah.Waterland@Sun.COM #include <grp.h>
41*9781SMoriah.Waterland@Sun.COM #include <locale.h>
42*9781SMoriah.Waterland@Sun.COM #include <libintl.h>
43*9781SMoriah.Waterland@Sun.COM #include <pkglib.h>
44*9781SMoriah.Waterland@Sun.COM #include "install.h"
45*9781SMoriah.Waterland@Sun.COM #include "libadm.h"
46*9781SMoriah.Waterland@Sun.COM #include "libinst.h"
47*9781SMoriah.Waterland@Sun.COM #include "pkginstall.h"
48*9781SMoriah.Waterland@Sun.COM #include "messages.h"
49*9781SMoriah.Waterland@Sun.COM
50*9781SMoriah.Waterland@Sun.COM extern char tmpdir[], instdir[];
51*9781SMoriah.Waterland@Sun.COM extern int pkgverbose;
52*9781SMoriah.Waterland@Sun.COM
53*9781SMoriah.Waterland@Sun.COM static int do_exec(int update, char *script, char *output,
54*9781SMoriah.Waterland@Sun.COM char *inport, char *alt_user);
55*9781SMoriah.Waterland@Sun.COM static char path[PATH_MAX];
56*9781SMoriah.Waterland@Sun.COM static char *resppath = NULL;
57*9781SMoriah.Waterland@Sun.COM static int fd;
58*9781SMoriah.Waterland@Sun.COM static int respfile_defined = 0;
59*9781SMoriah.Waterland@Sun.COM static int respfile_ro = 0; /* read only resp file */
60*9781SMoriah.Waterland@Sun.COM
61*9781SMoriah.Waterland@Sun.COM /*
62*9781SMoriah.Waterland@Sun.COM * This informs the calling routine if a read-only response file has been
63*9781SMoriah.Waterland@Sun.COM * provided on the command line.
64*9781SMoriah.Waterland@Sun.COM */
65*9781SMoriah.Waterland@Sun.COM int
rdonly_respfile(void)66*9781SMoriah.Waterland@Sun.COM rdonly_respfile(void)
67*9781SMoriah.Waterland@Sun.COM {
68*9781SMoriah.Waterland@Sun.COM return (respfile_ro);
69*9781SMoriah.Waterland@Sun.COM }
70*9781SMoriah.Waterland@Sun.COM
71*9781SMoriah.Waterland@Sun.COM int
is_a_respfile(void)72*9781SMoriah.Waterland@Sun.COM is_a_respfile(void)
73*9781SMoriah.Waterland@Sun.COM {
74*9781SMoriah.Waterland@Sun.COM return (respfile_defined);
75*9781SMoriah.Waterland@Sun.COM }
76*9781SMoriah.Waterland@Sun.COM
77*9781SMoriah.Waterland@Sun.COM /*
78*9781SMoriah.Waterland@Sun.COM * This function creates a working copy of the checkinstall script.
79*9781SMoriah.Waterland@Sun.COM * This is needed in situations where the packages parent directories modes
80*9781SMoriah.Waterland@Sun.COM * are set too restrictively, i.e. 700.
81*9781SMoriah.Waterland@Sun.COM *
82*9781SMoriah.Waterland@Sun.COM * Returns: A pointer to the location of the copied checkinstall
83*9781SMoriah.Waterland@Sun.COM * script or NULL
84*9781SMoriah.Waterland@Sun.COM */
85*9781SMoriah.Waterland@Sun.COM
86*9781SMoriah.Waterland@Sun.COM char *
dup_chkinstall(char * script)87*9781SMoriah.Waterland@Sun.COM dup_chkinstall(char *script)
88*9781SMoriah.Waterland@Sun.COM {
89*9781SMoriah.Waterland@Sun.COM char *dstpath;
90*9781SMoriah.Waterland@Sun.COM size_t dstpathLen;
91*9781SMoriah.Waterland@Sun.COM int r;
92*9781SMoriah.Waterland@Sun.COM static char *tmpname = "checkinstallXXXXXX";
93*9781SMoriah.Waterland@Sun.COM
94*9781SMoriah.Waterland@Sun.COM /* determine length for destination script path */
95*9781SMoriah.Waterland@Sun.COM
96*9781SMoriah.Waterland@Sun.COM dstpathLen = strlen(tmpdir) + strlen(tmpname) + 3;
97*9781SMoriah.Waterland@Sun.COM
98*9781SMoriah.Waterland@Sun.COM /* allocate storage to hold destination script path */
99*9781SMoriah.Waterland@Sun.COM
100*9781SMoriah.Waterland@Sun.COM dstpath = (char *)malloc(dstpathLen);
101*9781SMoriah.Waterland@Sun.COM if (dstpath == (char *)NULL) {
102*9781SMoriah.Waterland@Sun.COM return ((char *)NULL);
103*9781SMoriah.Waterland@Sun.COM }
104*9781SMoriah.Waterland@Sun.COM
105*9781SMoriah.Waterland@Sun.COM /* create destination script path */
106*9781SMoriah.Waterland@Sun.COM
107*9781SMoriah.Waterland@Sun.COM (void) snprintf(dstpath, dstpathLen, "%s/%s", tmpdir, tmpname);
108*9781SMoriah.Waterland@Sun.COM
109*9781SMoriah.Waterland@Sun.COM if (mktemp(dstpath) == NULL) {
110*9781SMoriah.Waterland@Sun.COM progerr(ERR_TMPFILE_CHK);
111*9781SMoriah.Waterland@Sun.COM (void) free(dstpath);
112*9781SMoriah.Waterland@Sun.COM return (NULL);
113*9781SMoriah.Waterland@Sun.COM }
114*9781SMoriah.Waterland@Sun.COM
115*9781SMoriah.Waterland@Sun.COM /* make copy of script */
116*9781SMoriah.Waterland@Sun.COM
117*9781SMoriah.Waterland@Sun.COM r = copyf(script, dstpath, (time_t)0);
118*9781SMoriah.Waterland@Sun.COM if (r != 0) {
119*9781SMoriah.Waterland@Sun.COM progerr(ERR_CANNOT_COPY, script, dstpath);
120*9781SMoriah.Waterland@Sun.COM return (NULL);
121*9781SMoriah.Waterland@Sun.COM }
122*9781SMoriah.Waterland@Sun.COM
123*9781SMoriah.Waterland@Sun.COM /* Make the copy of the script readable by all */
124*9781SMoriah.Waterland@Sun.COM
125*9781SMoriah.Waterland@Sun.COM if (chmod(dstpath, 0444) != 0) {
126*9781SMoriah.Waterland@Sun.COM progerr(ERR_CHMOD_CHK);
127*9781SMoriah.Waterland@Sun.COM (void) free(dstpath);
128*9781SMoriah.Waterland@Sun.COM return (NULL);
129*9781SMoriah.Waterland@Sun.COM }
130*9781SMoriah.Waterland@Sun.COM
131*9781SMoriah.Waterland@Sun.COM return (dstpath);
132*9781SMoriah.Waterland@Sun.COM }
133*9781SMoriah.Waterland@Sun.COM
134*9781SMoriah.Waterland@Sun.COM /*
135*9781SMoriah.Waterland@Sun.COM * This function creates a temporary working copy of a read-only response
136*9781SMoriah.Waterland@Sun.COM * file. It changes the resppath pointer to point to the working copy.
137*9781SMoriah.Waterland@Sun.COM */
138*9781SMoriah.Waterland@Sun.COM static int
dup_respfile(void)139*9781SMoriah.Waterland@Sun.COM dup_respfile(void)
140*9781SMoriah.Waterland@Sun.COM {
141*9781SMoriah.Waterland@Sun.COM char tpath[PATH_MAX];
142*9781SMoriah.Waterland@Sun.COM int r;
143*9781SMoriah.Waterland@Sun.COM
144*9781SMoriah.Waterland@Sun.COM (void) strlcpy(tpath, path, sizeof (tpath));
145*9781SMoriah.Waterland@Sun.COM
146*9781SMoriah.Waterland@Sun.COM (void) snprintf(path, sizeof (path), "%s/respXXXXXX", tmpdir);
147*9781SMoriah.Waterland@Sun.COM
148*9781SMoriah.Waterland@Sun.COM resppath = mktemp(path);
149*9781SMoriah.Waterland@Sun.COM if (resppath == NULL) {
150*9781SMoriah.Waterland@Sun.COM progerr(ERR_TMPRESP);
151*9781SMoriah.Waterland@Sun.COM return (99);
152*9781SMoriah.Waterland@Sun.COM }
153*9781SMoriah.Waterland@Sun.COM
154*9781SMoriah.Waterland@Sun.COM /* Copy the contents of the user's response file to the working copy. */
155*9781SMoriah.Waterland@Sun.COM
156*9781SMoriah.Waterland@Sun.COM r = copyf(tpath, resppath, (time_t)0);
157*9781SMoriah.Waterland@Sun.COM if (r != 0) {
158*9781SMoriah.Waterland@Sun.COM progerr(ERR_NORESPCOPY, tpath, resppath);
159*9781SMoriah.Waterland@Sun.COM return (99);
160*9781SMoriah.Waterland@Sun.COM }
161*9781SMoriah.Waterland@Sun.COM
162*9781SMoriah.Waterland@Sun.COM /*
163*9781SMoriah.Waterland@Sun.COM * Make it writable by the non-privileged installation user-id,
164*9781SMoriah.Waterland@Sun.COM * but readable by the world.
165*9781SMoriah.Waterland@Sun.COM */
166*9781SMoriah.Waterland@Sun.COM
167*9781SMoriah.Waterland@Sun.COM if (chmod(resppath, 0644) != 0) {
168*9781SMoriah.Waterland@Sun.COM progerr(ERR_CHMOD, resppath);
169*9781SMoriah.Waterland@Sun.COM return (99);
170*9781SMoriah.Waterland@Sun.COM }
171*9781SMoriah.Waterland@Sun.COM
172*9781SMoriah.Waterland@Sun.COM respfile_ro = 0;
173*9781SMoriah.Waterland@Sun.COM
174*9781SMoriah.Waterland@Sun.COM return (0);
175*9781SMoriah.Waterland@Sun.COM }
176*9781SMoriah.Waterland@Sun.COM
177*9781SMoriah.Waterland@Sun.COM /*
178*9781SMoriah.Waterland@Sun.COM * This function establishes the response file passed on the command line if
179*9781SMoriah.Waterland@Sun.COM * it's called with a valid string. If called with NULL, it checks to see if
180*9781SMoriah.Waterland@Sun.COM * there's a response file already. If there isn't, it creates a temporary.
181*9781SMoriah.Waterland@Sun.COM */
182*9781SMoriah.Waterland@Sun.COM int
set_respfile(char * respfile,char * pkginst,int resp_stat)183*9781SMoriah.Waterland@Sun.COM set_respfile(char *respfile, char *pkginst, int resp_stat)
184*9781SMoriah.Waterland@Sun.COM {
185*9781SMoriah.Waterland@Sun.COM if (respfile == NULL && !respfile_defined) {
186*9781SMoriah.Waterland@Sun.COM /* A temporary response file needs to be constructed. */
187*9781SMoriah.Waterland@Sun.COM (void) snprintf(path, sizeof (path), "%s/respXXXXXX", tmpdir);
188*9781SMoriah.Waterland@Sun.COM resppath = mktemp(path);
189*9781SMoriah.Waterland@Sun.COM if (resppath == NULL) {
190*9781SMoriah.Waterland@Sun.COM progerr(ERR_TMPRESP);
191*9781SMoriah.Waterland@Sun.COM return (99);
192*9781SMoriah.Waterland@Sun.COM }
193*9781SMoriah.Waterland@Sun.COM } else {
194*9781SMoriah.Waterland@Sun.COM /* OK, we're being passed a response file or directory. */
195*9781SMoriah.Waterland@Sun.COM if (isdir(respfile) == 0) {
196*9781SMoriah.Waterland@Sun.COM (void) snprintf(path, sizeof (path),
197*9781SMoriah.Waterland@Sun.COM "%s/%s", respfile, pkginst);
198*9781SMoriah.Waterland@Sun.COM } else {
199*9781SMoriah.Waterland@Sun.COM (void) strlcpy(path, respfile, sizeof (path));
200*9781SMoriah.Waterland@Sun.COM }
201*9781SMoriah.Waterland@Sun.COM
202*9781SMoriah.Waterland@Sun.COM resppath = path;
203*9781SMoriah.Waterland@Sun.COM respfile_ro = resp_stat;
204*9781SMoriah.Waterland@Sun.COM }
205*9781SMoriah.Waterland@Sun.COM
206*9781SMoriah.Waterland@Sun.COM respfile_defined++;
207*9781SMoriah.Waterland@Sun.COM
208*9781SMoriah.Waterland@Sun.COM return (0);
209*9781SMoriah.Waterland@Sun.COM }
210*9781SMoriah.Waterland@Sun.COM
211*9781SMoriah.Waterland@Sun.COM /* This exposes the working response file. */
212*9781SMoriah.Waterland@Sun.COM char *
get_respfile(void)213*9781SMoriah.Waterland@Sun.COM get_respfile(void)
214*9781SMoriah.Waterland@Sun.COM {
215*9781SMoriah.Waterland@Sun.COM return (resppath);
216*9781SMoriah.Waterland@Sun.COM }
217*9781SMoriah.Waterland@Sun.COM
218*9781SMoriah.Waterland@Sun.COM /*
219*9781SMoriah.Waterland@Sun.COM * Execute the request script if present assuming the response file
220*9781SMoriah.Waterland@Sun.COM * isn't read only.
221*9781SMoriah.Waterland@Sun.COM */
222*9781SMoriah.Waterland@Sun.COM int
reqexec(int update,char * script,int non_abi_scripts,boolean_t enable_root_user)223*9781SMoriah.Waterland@Sun.COM reqexec(int update, char *script, int non_abi_scripts,
224*9781SMoriah.Waterland@Sun.COM boolean_t enable_root_user)
225*9781SMoriah.Waterland@Sun.COM {
226*9781SMoriah.Waterland@Sun.COM char *req_user;
227*9781SMoriah.Waterland@Sun.COM
228*9781SMoriah.Waterland@Sun.COM /*
229*9781SMoriah.Waterland@Sun.COM * determine which alternative user to execute the request script as
230*9781SMoriah.Waterland@Sun.COM * if the default user "install" is not defined.
231*9781SMoriah.Waterland@Sun.COM */
232*9781SMoriah.Waterland@Sun.COM
233*9781SMoriah.Waterland@Sun.COM if (enable_root_user == B_TRUE) {
234*9781SMoriah.Waterland@Sun.COM /* use the root user */
235*9781SMoriah.Waterland@Sun.COM req_user = CHK_USER_ROOT;
236*9781SMoriah.Waterland@Sun.COM } else if (non_abi_scripts != 0) {
237*9781SMoriah.Waterland@Sun.COM /* non-compliant package user */
238*9781SMoriah.Waterland@Sun.COM req_user = CHK_USER_NON;
239*9781SMoriah.Waterland@Sun.COM } else {
240*9781SMoriah.Waterland@Sun.COM /* standard non-privileged user */
241*9781SMoriah.Waterland@Sun.COM req_user = CHK_USER_ALT;
242*9781SMoriah.Waterland@Sun.COM }
243*9781SMoriah.Waterland@Sun.COM
244*9781SMoriah.Waterland@Sun.COM /*
245*9781SMoriah.Waterland@Sun.COM * If we can't get to the the script or the response file, skip this.
246*9781SMoriah.Waterland@Sun.COM */
247*9781SMoriah.Waterland@Sun.COM if (access(script, F_OK) != 0 || respfile_ro)
248*9781SMoriah.Waterland@Sun.COM return (0);
249*9781SMoriah.Waterland@Sun.COM
250*9781SMoriah.Waterland@Sun.COM /* No interact means no interact. */
251*9781SMoriah.Waterland@Sun.COM if (echoGetFlag() == B_FALSE) {
252*9781SMoriah.Waterland@Sun.COM ptext(stderr, ERR_INTR);
253*9781SMoriah.Waterland@Sun.COM return (5);
254*9781SMoriah.Waterland@Sun.COM }
255*9781SMoriah.Waterland@Sun.COM
256*9781SMoriah.Waterland@Sun.COM /* If there's no response file, create one. */
257*9781SMoriah.Waterland@Sun.COM if (!respfile_defined)
258*9781SMoriah.Waterland@Sun.COM if (set_respfile(NULL, NULL, 0))
259*9781SMoriah.Waterland@Sun.COM return (99);
260*9781SMoriah.Waterland@Sun.COM
261*9781SMoriah.Waterland@Sun.COM /* Clear out the old response file (if there is one). */
262*9781SMoriah.Waterland@Sun.COM if ((access(resppath, F_OK) == 0) && unlink(resppath)) {
263*9781SMoriah.Waterland@Sun.COM progerr(ERR_RMRESP, resppath);
264*9781SMoriah.Waterland@Sun.COM return (99);
265*9781SMoriah.Waterland@Sun.COM }
266*9781SMoriah.Waterland@Sun.COM
267*9781SMoriah.Waterland@Sun.COM /*
268*9781SMoriah.Waterland@Sun.COM * Create a zero length response file which is only writable
269*9781SMoriah.Waterland@Sun.COM * by the non-privileged installation user-id, but is readable
270*9781SMoriah.Waterland@Sun.COM * by the world
271*9781SMoriah.Waterland@Sun.COM */
272*9781SMoriah.Waterland@Sun.COM if ((fd = open(resppath, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, 0644)) < 0) {
273*9781SMoriah.Waterland@Sun.COM progerr(ERR_CRERESP, resppath);
274*9781SMoriah.Waterland@Sun.COM return (99);
275*9781SMoriah.Waterland@Sun.COM }
276*9781SMoriah.Waterland@Sun.COM (void) close(fd);
277*9781SMoriah.Waterland@Sun.COM
278*9781SMoriah.Waterland@Sun.COM return (do_exec(update, script, resppath, REQ_STDIN, req_user));
279*9781SMoriah.Waterland@Sun.COM }
280*9781SMoriah.Waterland@Sun.COM
281*9781SMoriah.Waterland@Sun.COM int
chkexec(int update,char * script)282*9781SMoriah.Waterland@Sun.COM chkexec(int update, char *script)
283*9781SMoriah.Waterland@Sun.COM {
284*9781SMoriah.Waterland@Sun.COM /*
285*9781SMoriah.Waterland@Sun.COM * If we're up against a read-only response file from the command
286*9781SMoriah.Waterland@Sun.COM * line. Create a working copy.
287*9781SMoriah.Waterland@Sun.COM */
288*9781SMoriah.Waterland@Sun.COM if (respfile_ro) {
289*9781SMoriah.Waterland@Sun.COM if (dup_respfile())
290*9781SMoriah.Waterland@Sun.COM
291*9781SMoriah.Waterland@Sun.COM return (99);
292*9781SMoriah.Waterland@Sun.COM
293*9781SMoriah.Waterland@Sun.COM /* Make sure we can get to it. */
294*9781SMoriah.Waterland@Sun.COM if ((access(resppath, F_OK) != 0)) {
295*9781SMoriah.Waterland@Sun.COM progerr(ERR_ACCRESP, resppath);
296*9781SMoriah.Waterland@Sun.COM return (7);
297*9781SMoriah.Waterland@Sun.COM }
298*9781SMoriah.Waterland@Sun.COM }
299*9781SMoriah.Waterland@Sun.COM
300*9781SMoriah.Waterland@Sun.COM /* If there's no response file, create a fresh one. */
301*9781SMoriah.Waterland@Sun.COM else if (!respfile_defined) {
302*9781SMoriah.Waterland@Sun.COM if (set_respfile(NULL, NULL, 0))
303*9781SMoriah.Waterland@Sun.COM return (99);
304*9781SMoriah.Waterland@Sun.COM
305*9781SMoriah.Waterland@Sun.COM /*
306*9781SMoriah.Waterland@Sun.COM * create a zero length response file which is only writable
307*9781SMoriah.Waterland@Sun.COM * by the non-priveledged installation user-id, but is readable
308*9781SMoriah.Waterland@Sun.COM * by the world
309*9781SMoriah.Waterland@Sun.COM */
310*9781SMoriah.Waterland@Sun.COM fd = open(resppath, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, 0644);
311*9781SMoriah.Waterland@Sun.COM if (fd < 0) {
312*9781SMoriah.Waterland@Sun.COM progerr(ERR_CRERESP, resppath);
313*9781SMoriah.Waterland@Sun.COM return (99);
314*9781SMoriah.Waterland@Sun.COM }
315*9781SMoriah.Waterland@Sun.COM (void) close(fd);
316*9781SMoriah.Waterland@Sun.COM }
317*9781SMoriah.Waterland@Sun.COM
318*9781SMoriah.Waterland@Sun.COM return (do_exec(update, script, resppath, CHK_STDIN, CHK_USER_ALT));
319*9781SMoriah.Waterland@Sun.COM }
320*9781SMoriah.Waterland@Sun.COM
321*9781SMoriah.Waterland@Sun.COM static int
do_exec(int update,char * script,char * output,char * inport,char * alt_user)322*9781SMoriah.Waterland@Sun.COM do_exec(int update, char *script, char *output, char *inport, char *alt_user)
323*9781SMoriah.Waterland@Sun.COM {
324*9781SMoriah.Waterland@Sun.COM char *gname;
325*9781SMoriah.Waterland@Sun.COM char *tmp_script;
326*9781SMoriah.Waterland@Sun.COM char *uname;
327*9781SMoriah.Waterland@Sun.COM gid_t instgid;
328*9781SMoriah.Waterland@Sun.COM int retcode = 0;
329*9781SMoriah.Waterland@Sun.COM struct group *grp;
330*9781SMoriah.Waterland@Sun.COM struct passwd *pwp;
331*9781SMoriah.Waterland@Sun.COM uid_t instuid;
332*9781SMoriah.Waterland@Sun.COM
333*9781SMoriah.Waterland@Sun.COM /*
334*9781SMoriah.Waterland@Sun.COM * Determine which user to run the request script as:
335*9781SMoriah.Waterland@Sun.COM * - if CHK_USER is a valid user, run the script as CHK_USER
336*9781SMoriah.Waterland@Sun.COM * - otherwise, if alt_user is a valid user, run the script
337*9781SMoriah.Waterland@Sun.COM * -- as alt_user
338*9781SMoriah.Waterland@Sun.COM * - otherwise, output an error message and return failure
339*9781SMoriah.Waterland@Sun.COM */
340*9781SMoriah.Waterland@Sun.COM
341*9781SMoriah.Waterland@Sun.COM if ((pwp = getpwnam(CHK_USER)) != (struct passwd *)NULL) {
342*9781SMoriah.Waterland@Sun.COM instuid = pwp->pw_uid;
343*9781SMoriah.Waterland@Sun.COM uname = CHK_USER;
344*9781SMoriah.Waterland@Sun.COM } else if ((pwp = getpwnam(alt_user)) != (struct passwd *)NULL) {
345*9781SMoriah.Waterland@Sun.COM instuid = pwp->pw_uid;
346*9781SMoriah.Waterland@Sun.COM uname = alt_user;
347*9781SMoriah.Waterland@Sun.COM } else {
348*9781SMoriah.Waterland@Sun.COM ptext(stderr, ERR_BADUSER, CHK_USER, CHK_USER_ALT);
349*9781SMoriah.Waterland@Sun.COM return (1);
350*9781SMoriah.Waterland@Sun.COM }
351*9781SMoriah.Waterland@Sun.COM
352*9781SMoriah.Waterland@Sun.COM /*
353*9781SMoriah.Waterland@Sun.COM * Determine which group to run the request script as:
354*9781SMoriah.Waterland@Sun.COM * - If CHK_GRP is a valid group, run the script as CHK_GRP
355*9781SMoriah.Waterland@Sun.COM * - otherwise, assume group "1" user "other"
356*9781SMoriah.Waterland@Sun.COM */
357*9781SMoriah.Waterland@Sun.COM
358*9781SMoriah.Waterland@Sun.COM if ((grp = getgrnam(CHK_GRP)) != (struct group *)NULL) {
359*9781SMoriah.Waterland@Sun.COM instgid = grp->gr_gid;
360*9781SMoriah.Waterland@Sun.COM gname = CHK_GRP;
361*9781SMoriah.Waterland@Sun.COM } else {
362*9781SMoriah.Waterland@Sun.COM instgid = (gid_t)1; /* "other" group id */
363*9781SMoriah.Waterland@Sun.COM gname = "other"; /* "other" group name */
364*9781SMoriah.Waterland@Sun.COM }
365*9781SMoriah.Waterland@Sun.COM
366*9781SMoriah.Waterland@Sun.COM echoDebug(DBG_DO_EXEC_REQUEST_USER, script, output, uname, instuid,
367*9781SMoriah.Waterland@Sun.COM gname, instgid);
368*9781SMoriah.Waterland@Sun.COM
369*9781SMoriah.Waterland@Sun.COM (void) chown(output, instuid, instgid);
370*9781SMoriah.Waterland@Sun.COM
371*9781SMoriah.Waterland@Sun.COM /*
372*9781SMoriah.Waterland@Sun.COM * Copy the checkinstall script to tmpdir in case parent directories
373*9781SMoriah.Waterland@Sun.COM * are restrictive, i.e. 700. Only do this for non updates, i.e.
374*9781SMoriah.Waterland@Sun.COM * package installs and not patch package installs.
375*9781SMoriah.Waterland@Sun.COM */
376*9781SMoriah.Waterland@Sun.COM if (update) {
377*9781SMoriah.Waterland@Sun.COM tmp_script = strdup(script);
378*9781SMoriah.Waterland@Sun.COM } else if ((tmp_script = dup_chkinstall(script)) == NULL) {
379*9781SMoriah.Waterland@Sun.COM /* Use the original checkinstall script */
380*9781SMoriah.Waterland@Sun.COM tmp_script = strdup(script);
381*9781SMoriah.Waterland@Sun.COM }
382*9781SMoriah.Waterland@Sun.COM
383*9781SMoriah.Waterland@Sun.COM if (pkgverbose)
384*9781SMoriah.Waterland@Sun.COM retcode = pkgexecl(inport, CHK_STDOUT, uname, CHK_GRP, SHELL,
385*9781SMoriah.Waterland@Sun.COM "-x", tmp_script, output, NULL);
386*9781SMoriah.Waterland@Sun.COM else
387*9781SMoriah.Waterland@Sun.COM retcode = pkgexecl(inport, CHK_STDOUT, uname, CHK_GRP, SHELL,
388*9781SMoriah.Waterland@Sun.COM tmp_script, output, NULL);
389*9781SMoriah.Waterland@Sun.COM
390*9781SMoriah.Waterland@Sun.COM free(tmp_script);
391*9781SMoriah.Waterland@Sun.COM return (retcode);
392*9781SMoriah.Waterland@Sun.COM }
393