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