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