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