1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 /*
30  *	updatehome - Update the current label's $HOME copy and link files.
31  *
32  *		Update home reads the user's minimum label copy and link
33  *	control files (.copy_files and .link_files) which contain a list
34  *	of files to be copied and symbolically linked from the user's minimum
35  *	label $HOME to the user's current label's $HOME.
36  *
37  *		This is done by the Trusted Solaris dtsession whenever a
38  *	newly labeled workspace is created so that the user's favorite
39  *	files are available for use.  For example the user probably
40  *	wants a symlink to .profile, .login, .cshrc, .exrc, .mailrc, ~/bin,
41  *	... .  updatehome provides a convient mechanism for accomplishing
42  *	this.  The user may add any set of files either to be copied
43  *	(.copy_files), or symbolically linked (.link_files).
44  *
45  *		Files should not include embedded MLDs.
46  *
47  *	Entry	options = c, if replace existing current label $HOME copies
48  *			     (default is to ignore existing).
49  *			  d, if to print debug trace msgs (internal use only).
50  *			  i, if to ignore errors encountered (default is to
51  *			     abort).
52  *			  m, if to suppress error diagnostics -- perror
53  *			     (internal use only).
54  *			  r, if replace existing current label $HOME copies or
55  *			     symbolic links  -- implies c and s (default is to
56  *			     ignore existing).
57  *			  s, if replace existing current label $HOME symbolic
58  *			     links (default is to ignore existing).
59  *
60  *	Exit	stderr = diagnostic messages.
61  *		exis status = 0, no errors noted.
62  *			      1, if errors noted.
63  *
64  *	Calls	__setupfiles (which does all the real work).
65  */
66 
67 
68 /*
69  *		There is a private contract between __setupfiles in this
70  *	directory and login.  Changes made to __setupfiles may need to be
71  *	reflected in the source for login.
72  *
73  *	G.Winiger 96/11/03
74  */
75 
76 
77 #include <locale.h>
78 #include <pwd.h>
79 #include <stdio.h>
80 #include <stdlib.h>
81 #include <unistd.h>
82 
83 #include <sys/types.h>
84 
85 #include <tsol/label.h>
86 #include <sys/tsol/label_macro.h>
87 #include <user_attr.h>
88 
89 #include "setupfiles.h"
90 
91 #if !defined(TEXT_DOMAIN)
92 #define	TEXT_DOMAIN	"SYS_TEST"
93 #endif	/* !defined(TEXT_DOMAIN) */
94 
95 int
96 main(int argc, char **argv)
97 {
98 	int		opt;		/* option switch value */
99 	int		flags;		/* setupfiles flags */
100 	uid_t		uid;
101 	extern int	opterr;		/* getopt error flag */
102 	char		*kv_str = NULL;
103 	struct passwd	*pwd;		/* current user's password file entry */
104 	userattr_t	*userp = NULL;	/* current user's user_attr entry */
105 	m_label_t	*min_sl;
106 	m_label_t	*clearance;
107 
108 	(void) setlocale(LC_ALL, "");
109 	(void) textdomain(TEXT_DOMAIN);
110 
111 	flags = DIAG;
112 	opterr = 0;	/* handle errors here */
113 
114 	while ((opt = getopt(argc, argv, "cdimrs")) != EOF) {
115 		switch (opt) {
116 		case 'c':	/* replace existing copy */
117 			flags |= REPC;
118 			break;
119 
120 		case 'd':	/* debug */
121 			flags |= DBUG;
122 			break;
123 
124 		case 'i':	/* ignore copy/link errors */
125 			flags |= IGNE;
126 			break;
127 
128 		case 'm':	/* suppress error diagnostic (perror) */
129 				/* prints */
130 			flags &= ~DIAG;
131 			break;
132 
133 		case 'r':		/* replace existing */
134 			flags |= (REPC | REPL);
135 			break;
136 
137 		case 's':	/* replace existing symbolic links */
138 			flags |= REPL;
139 			break;
140 
141 		case '?':		/* switch error */
142 			(void) fprintf(stderr, gettext("Bad option -%c.\n"),
143 			    (char)optopt);
144 
145 		default:
146 			(void) fprintf(stderr, gettext("usage: %s [-cirs].\n"),
147 			    argv[0]);
148 			exit(1);
149 			/*NOTREACHED*/
150 		}  /* switch (opt) */
151 	}  /* while ((opt = getopt()) */
152 
153 	uid = getuid();
154 
155 	if ((pwd = getpwuid(uid)) == (struct passwd *)0) {
156 
157 		(void) fprintf(stderr,
158 		    gettext("Unable to get password entry for uid %d.\n"), uid);
159 		exit(1);
160 	}
161 
162 	min_sl = m_label_alloc(MAC_LABEL);
163 	clearance = m_label_alloc(USER_CLEAR);
164 
165 	if (((userp = getusernam(pwd->pw_name)) == NULL) ||
166 	    ((kv_str = kva_match(userp->attr, USERATTR_MINLABEL)) == NULL)) {
167 
168 		if (userdefs(min_sl, clearance) == -1) {
169 			(void) fprintf(stderr,
170 			    gettext("Unable to get default user labels.\n"));
171 			exit(1);
172 		}
173 	}
174 
175 	if (kv_str != NULL) {
176 
177 		if (str_to_label(kv_str, &min_sl, MAC_LABEL, L_NO_CORRECTION,
178 		    NULL) == -1) {
179 			(void) fprintf(stderr,
180 			    gettext("stobsl failure on min_label for user"
181 			    " %s.\n"), pwd->pw_name);
182 			exit(1);
183 		}
184 	}
185 
186 	if (__setupfiles(pwd, min_sl, flags) != 0) {
187 
188 		(void) fprintf(stderr, gettext("%s failed.\n"), argv[0]);
189 		exit(1);
190 	}
191 
192 	return (0);
193 }  /* update home */
194