xref: /titanic_51/usr/src/lib/libsmbfs/smb/keychain.c (revision 4bff34e37def8a90f9194d81bc345c52ba20086a)
1*4bff34e3Sthurlow /*
2*4bff34e3Sthurlow  * CDDL HEADER START
3*4bff34e3Sthurlow  *
4*4bff34e3Sthurlow  * The contents of this file are subject to the terms of the
5*4bff34e3Sthurlow  * Common Development and Distribution License (the "License").
6*4bff34e3Sthurlow  * You may not use this file except in compliance with the License.
7*4bff34e3Sthurlow  *
8*4bff34e3Sthurlow  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*4bff34e3Sthurlow  * or http://www.opensolaris.org/os/licensing.
10*4bff34e3Sthurlow  * See the License for the specific language governing permissions
11*4bff34e3Sthurlow  * and limitations under the License.
12*4bff34e3Sthurlow  *
13*4bff34e3Sthurlow  * When distributing Covered Code, include this CDDL HEADER in each
14*4bff34e3Sthurlow  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*4bff34e3Sthurlow  * If applicable, add the following below this CDDL HEADER, with the
16*4bff34e3Sthurlow  * fields enclosed by brackets "[]" replaced with your own identifying
17*4bff34e3Sthurlow  * information: Portions Copyright [yyyy] [name of copyright owner]
18*4bff34e3Sthurlow  *
19*4bff34e3Sthurlow  * CDDL HEADER END
20*4bff34e3Sthurlow  */
21*4bff34e3Sthurlow 
22*4bff34e3Sthurlow /*
23*4bff34e3Sthurlow  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24*4bff34e3Sthurlow  * Use is subject to license terms.
25*4bff34e3Sthurlow  */
26*4bff34e3Sthurlow 
27*4bff34e3Sthurlow #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*4bff34e3Sthurlow 
29*4bff34e3Sthurlow /*
30*4bff34e3Sthurlow  * External interface to the libsmbfs/netsmb keychain
31*4bff34e3Sthurlow  * storage mechanism.  This interface is consumed by
32*4bff34e3Sthurlow  * the "smbutil" commands: login, logout, ...
33*4bff34e3Sthurlow  * and by the SMBFS PAM module.
34*4bff34e3Sthurlow  */
35*4bff34e3Sthurlow 
36*4bff34e3Sthurlow #include <sys/types.h>
37*4bff34e3Sthurlow 
38*4bff34e3Sthurlow #include <errno.h>
39*4bff34e3Sthurlow #include <stdio.h>
40*4bff34e3Sthurlow #include <string.h>
41*4bff34e3Sthurlow #include <unistd.h>
42*4bff34e3Sthurlow #include <libintl.h>
43*4bff34e3Sthurlow 
44*4bff34e3Sthurlow #include <netsmb/smb_dev.h>
45*4bff34e3Sthurlow #include <netsmb/smb_lib.h>
46*4bff34e3Sthurlow #include <netsmb/smb_keychain.h>
47*4bff34e3Sthurlow 
48*4bff34e3Sthurlow #include <cflib.h>
49*4bff34e3Sthurlow 
50*4bff34e3Sthurlow /* common func. for add/del/chk */
51*4bff34e3Sthurlow static int
52*4bff34e3Sthurlow smbfs_keychain_cmn(
53*4bff34e3Sthurlow 	int cmd,
54*4bff34e3Sthurlow 	uid_t uid,
55*4bff34e3Sthurlow 	const char *dom,
56*4bff34e3Sthurlow 	const char *usr,
57*4bff34e3Sthurlow 	const char *pass)
58*4bff34e3Sthurlow {
59*4bff34e3Sthurlow 	smbioc_pk_t pk;
60*4bff34e3Sthurlow 	int err, fd;
61*4bff34e3Sthurlow 
62*4bff34e3Sthurlow 	memset(&pk, 0, sizeof (pk));
63*4bff34e3Sthurlow 
64*4bff34e3Sthurlow 	pk.pk_uid = uid;
65*4bff34e3Sthurlow 
66*4bff34e3Sthurlow 	switch (cmd) {
67*4bff34e3Sthurlow 
68*4bff34e3Sthurlow 	case SMBIOC_PK_ADD:
69*4bff34e3Sthurlow 		if (pass == NULL)
70*4bff34e3Sthurlow 			return (SMB_KEYCHAIN_BADPASSWD);
71*4bff34e3Sthurlow 		if (strlcpy(pk.pk_pass, pass, sizeof (pk.pk_pass)) >=
72*4bff34e3Sthurlow 		    sizeof (pk.pk_pass))
73*4bff34e3Sthurlow 			return (SMB_KEYCHAIN_BADPASSWD);
74*4bff34e3Sthurlow 		/* FALLTHROUGH */
75*4bff34e3Sthurlow 
76*4bff34e3Sthurlow 	case SMBIOC_PK_CHK:
77*4bff34e3Sthurlow 	case SMBIOC_PK_DEL:
78*4bff34e3Sthurlow 		if (dom == NULL)
79*4bff34e3Sthurlow 			return (SMB_KEYCHAIN_BADDOMAIN);
80*4bff34e3Sthurlow 		if (strlcpy(pk.pk_dom, dom, sizeof (pk.pk_dom)) >=
81*4bff34e3Sthurlow 		    sizeof (pk.pk_dom))
82*4bff34e3Sthurlow 			return (SMB_KEYCHAIN_BADDOMAIN);
83*4bff34e3Sthurlow 		if (usr == NULL)
84*4bff34e3Sthurlow 			return (SMB_KEYCHAIN_BADUSER);
85*4bff34e3Sthurlow 		if (strlcpy(pk.pk_usr, usr, sizeof (pk.pk_usr)) >=
86*4bff34e3Sthurlow 		    sizeof (pk.pk_usr))
87*4bff34e3Sthurlow 			return (SMB_KEYCHAIN_BADUSER);
88*4bff34e3Sthurlow 		break;
89*4bff34e3Sthurlow 
90*4bff34e3Sthurlow 	case SMBIOC_PK_DEL_OWNER:	/* all owned by the caller */
91*4bff34e3Sthurlow 	case SMBIOC_PK_DEL_EVERYONE:	/* all owned by everyone */
92*4bff34e3Sthurlow 		/*
93*4bff34e3Sthurlow 		 * These two do not copyin any args, but we'll
94*4bff34e3Sthurlow 		 * pass &pk here anyway just so we can use the
95*4bff34e3Sthurlow 		 * common code path below.
96*4bff34e3Sthurlow 		 */
97*4bff34e3Sthurlow 		break;
98*4bff34e3Sthurlow 
99*4bff34e3Sthurlow 	default:
100*4bff34e3Sthurlow 		return (SMB_KEYCHAIN_UNKNOWN);
101*4bff34e3Sthurlow 	}
102*4bff34e3Sthurlow 
103*4bff34e3Sthurlow 	fd = smb_open_driver();
104*4bff34e3Sthurlow 	if (fd < 0) {
105*4bff34e3Sthurlow 		err = SMB_KEYCHAIN_NODRIVER;
106*4bff34e3Sthurlow 		goto out;
107*4bff34e3Sthurlow 	}
108*4bff34e3Sthurlow 
109*4bff34e3Sthurlow 	err = 0;
110*4bff34e3Sthurlow 	if (ioctl(fd, cmd, &pk) < 0)
111*4bff34e3Sthurlow 		err = errno;
112*4bff34e3Sthurlow 
113*4bff34e3Sthurlow 	close(fd);
114*4bff34e3Sthurlow out:
115*4bff34e3Sthurlow 	memset(&pk, 0, sizeof (pk));
116*4bff34e3Sthurlow 	return (err);
117*4bff34e3Sthurlow }
118*4bff34e3Sthurlow 
119*4bff34e3Sthurlow /* Add a password to the keychain. */
120*4bff34e3Sthurlow int
121*4bff34e3Sthurlow smbfs_keychain_add(uid_t uid, const char *dom, const char *usr,
122*4bff34e3Sthurlow 	const char *pass)
123*4bff34e3Sthurlow {
124*4bff34e3Sthurlow 	return (smbfs_keychain_cmn(SMBIOC_PK_ADD, uid, dom, usr, pass));
125*4bff34e3Sthurlow }
126*4bff34e3Sthurlow 
127*4bff34e3Sthurlow /* Delete a password from the keychain. */
128*4bff34e3Sthurlow int
129*4bff34e3Sthurlow smbfs_keychain_del(uid_t uid, const char *dom, const char *usr)
130*4bff34e3Sthurlow {
131*4bff34e3Sthurlow 	return (smbfs_keychain_cmn(SMBIOC_PK_DEL, uid, dom, usr, NULL));
132*4bff34e3Sthurlow }
133*4bff34e3Sthurlow 
134*4bff34e3Sthurlow /*
135*4bff34e3Sthurlow  * Check for existence of a keychain entry.
136*4bff34e3Sthurlow  * Returns 0 if it exists, else ENOENT.
137*4bff34e3Sthurlow  */
138*4bff34e3Sthurlow int
139*4bff34e3Sthurlow smbfs_keychain_chk(const char *dom, const char *usr)
140*4bff34e3Sthurlow {
141*4bff34e3Sthurlow 	return (smbfs_keychain_cmn(SMBIOC_PK_CHK, (uid_t)-1, dom, usr, NULL));
142*4bff34e3Sthurlow }
143*4bff34e3Sthurlow 
144*4bff34e3Sthurlow /*
145*4bff34e3Sthurlow  * Delete all keychain entries owned by the caller.
146*4bff34e3Sthurlow  */
147*4bff34e3Sthurlow int
148*4bff34e3Sthurlow smbfs_keychain_del_owner()
149*4bff34e3Sthurlow {
150*4bff34e3Sthurlow 	return (smbfs_keychain_cmn(SMBIOC_PK_DEL_OWNER, getuid(), 0, 0, 0));
151*4bff34e3Sthurlow }
152*4bff34e3Sthurlow 
153*4bff34e3Sthurlow /*
154*4bff34e3Sthurlow  * Delete all keychain entries (regardless of onwer).
155*4bff34e3Sthurlow  * Requires super-user privliege.
156*4bff34e3Sthurlow  */
157*4bff34e3Sthurlow int
158*4bff34e3Sthurlow smbfs_keychain_del_everyone()
159*4bff34e3Sthurlow {
160*4bff34e3Sthurlow 	return (smbfs_keychain_cmn(SMBIOC_PK_DEL_EVERYONE, getuid(), 0, 0, 0));
161*4bff34e3Sthurlow }
162*4bff34e3Sthurlow 
163*4bff34e3Sthurlow 
164*4bff34e3Sthurlow /*
165*4bff34e3Sthurlow  * This is not really part of the keychain library,
166*4bff34e3Sthurlow  * but is typically needed in code that wants to
167*4bff34e3Sthurlow  * provide (editable) defaults for domain/user
168*4bff34e3Sthurlow  *
169*4bff34e3Sthurlow  * Get default domain and user names
170*4bff34e3Sthurlow  * Server name is optional.
171*4bff34e3Sthurlow  */
172*4bff34e3Sthurlow int
173*4bff34e3Sthurlow smbfs_default_dom_usr(const char *home, const char *server,
174*4bff34e3Sthurlow 	char *dom, int maxdom, char *usr, int maxusr)
175*4bff34e3Sthurlow {
176*4bff34e3Sthurlow 	struct smb_ctx sctx, *ctx = &sctx;
177*4bff34e3Sthurlow 	int err;
178*4bff34e3Sthurlow 
179*4bff34e3Sthurlow 	err = smb_ctx_init(ctx, 0, NULL, SMBL_VC, SMBL_VC, SMB_ST_ANY);
180*4bff34e3Sthurlow 	if (err)
181*4bff34e3Sthurlow 		return (err);
182*4bff34e3Sthurlow 	if (server)
183*4bff34e3Sthurlow 		smb_ctx_setserver(ctx, server);
184*4bff34e3Sthurlow 	if (home && *home)
185*4bff34e3Sthurlow 		ctx->ct_home = (char *)home;
186*4bff34e3Sthurlow 	err = smb_ctx_readrc(ctx);
187*4bff34e3Sthurlow 	if (err)
188*4bff34e3Sthurlow 		return (err);
189*4bff34e3Sthurlow 	if (smb_rc)
190*4bff34e3Sthurlow 		rc_close(smb_rc);
191*4bff34e3Sthurlow 
192*4bff34e3Sthurlow 	if (dom)
193*4bff34e3Sthurlow 		strlcpy(dom, ctx->ct_ssn.ioc_workgroup, maxdom);
194*4bff34e3Sthurlow 
195*4bff34e3Sthurlow 	if (usr)
196*4bff34e3Sthurlow 		strlcpy(usr, ctx->ct_ssn.ioc_user, maxusr);
197*4bff34e3Sthurlow 
198*4bff34e3Sthurlow 	return (0);
199*4bff34e3Sthurlow }
200