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