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