xref: /illumos-gate/usr/src/cmd/tsol/updatehome/updatehome.c (revision b6805bf78d2bbbeeaea8909a05623587b42d58b3)
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
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 
143 		default:
144 			(void) fprintf(stderr, gettext("usage: %s [-cirs].\n"),
145 			    argv[0]);
146 			exit(1);
147 			/*NOTREACHED*/
148 		}  /* switch (opt) */
149 	}  /* while ((opt = getopt()) */
150 
151 	uid = getuid();
152 
153 	if ((pwd = getpwuid(uid)) == (struct passwd *)0) {
154 
155 		(void) fprintf(stderr,
156 		    gettext("Unable to get password entry for uid %d.\n"), uid);
157 		exit(1);
158 	}
159 
160 	min_sl = m_label_alloc(MAC_LABEL);
161 	clearance = m_label_alloc(USER_CLEAR);
162 
163 	if (((userp = getusernam(pwd->pw_name)) == NULL) ||
164 	    ((kv_str = kva_match(userp->attr, USERATTR_MINLABEL)) == NULL)) {
165 
166 		if (userdefs(min_sl, clearance) == -1) {
167 			(void) fprintf(stderr,
168 			    gettext("Unable to get default user labels.\n"));
169 			exit(1);
170 		}
171 	}
172 
173 	if (kv_str != NULL) {
174 		if (str_to_label(kv_str, &min_sl, MAC_LABEL, L_NO_CORRECTION,
175 		    NULL) == -1) {
176 			(void) fprintf(stderr,
177 			    gettext("str_to_label failure on min_label for"
178 			    " user %s.\n"), pwd->pw_name);
179 			exit(1);
180 		}
181 	}
182 
183 	if (__setupfiles(pwd, min_sl, flags) != 0) {
184 
185 		(void) fprintf(stderr, gettext("%s failed.\n"), argv[0]);
186 		exit(1);
187 	}
188 
189 	return (0);
190 }  /* update home */
191