1 /* 2 * Copyright (c) 2000, Boris Popov 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by Boris Popov. 16 * 4. Neither the name of the author nor the names of any co-contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 * 32 * $Id: login.c,v 1.8 2004/03/19 01:49:48 lindak Exp $ 33 */ 34 35 #pragma ident "%Z%%M% %I% %E% SMI" 36 37 #include <sys/param.h> 38 #include <sys/errno.h> 39 #include <sys/stat.h> 40 41 #include <stdio.h> 42 #include <stdlib.h> 43 #include <strings.h> 44 #include <unistd.h> 45 #include <err.h> 46 #include <libintl.h> 47 48 #include <netsmb/smb_lib.h> 49 #include <netsmb/smb_keychain.h> 50 51 #include "common.h" 52 53 /* defaults */ 54 static char def_dom[256]; 55 static char def_usr[256]; 56 static char tmp_arg[256]; 57 58 59 /* 60 * Parse the string: domuser, which may be any of: 61 * "user@domain" or "domain/user" or "domain\\user" 62 * and return pointers to the domain and user parts. 63 * Modifies the string domuser in-place. Returned 64 * string pointers are within the string domusr. 65 */ 66 int 67 smbfs_parse_domuser(char *domuser, char **dom, char **usr) 68 { 69 const char sep[] = "@/\\"; 70 char sc, *p, *s1, *s2; 71 72 p = strpbrk(domuser, sep); 73 if (p == NULL) { 74 /* No separators - whole string is the user. */ 75 *dom = NULL; 76 *usr = domuser; 77 return (0); 78 } 79 80 /* Have two strings. */ 81 s1 = domuser; 82 sc = *p; /* Save the sep. char */ 83 *p++ = '\0'; /* zap it */ 84 s2 = p; 85 86 /* Enforce just one separator */ 87 p = strpbrk(s2, sep); 88 if (p) 89 return (-1); 90 91 /* 92 * Now, which order are they? 93 * "user@domain" or "domain/user" 94 */ 95 if (sc == '@') { 96 *usr = s1; 97 *dom = s2; 98 } else { 99 *dom = s1; 100 *usr = s2; 101 } 102 103 return (0); 104 } 105 106 void 107 login_usage(void) 108 { 109 printf(gettext("usage: smbutil login [-c] [[domain/]user]\n")); 110 printf(gettext(" smbutil login [-c] [user[@domain]]\n")); 111 exit(1); 112 } 113 114 int 115 cmd_login(int argc, char *argv[]) 116 { 117 static char prompt[64]; 118 char *dom, *usr, *pass; 119 int err, opt; 120 int check = 0; 121 122 while ((opt = getopt(argc, argv, "c")) != EOF) { 123 switch (opt) { 124 125 case 'c': /* smbutil login -c ... */ 126 check = 1; 127 break; 128 129 default: 130 login_usage(); 131 break; 132 } 133 } 134 135 dom = usr = NULL; 136 if (optind < argc) { 137 strcpy(tmp_arg, argv[optind]); 138 err = smbfs_parse_domuser(tmp_arg, &dom, &usr); 139 if (err) 140 errx(1, gettext("failed to parse %s"), argv[optind]); 141 optind++; 142 } 143 if (optind != argc) 144 login_usage(); 145 146 if (dom == NULL || usr == NULL) { 147 err = smbfs_default_dom_usr(NULL, NULL, 148 def_dom, sizeof (def_dom), 149 def_usr, sizeof (def_usr)); 150 if (err) 151 errx(1, gettext("failed to get defaults")); 152 } 153 if (dom == NULL) 154 dom = def_dom; 155 else 156 nls_str_upper(dom, dom); 157 if (usr == NULL) 158 usr = def_usr; 159 160 if (check) { 161 err = smbfs_keychain_chk(dom, usr); 162 if (!err) 163 printf(gettext("Keychain entry exists.\n")); 164 else 165 printf(gettext("Keychain entry not found.\n")); 166 return (0); 167 } 168 169 snprintf(prompt, sizeof (prompt), 170 gettext("Password for %s/%s:"), dom, usr); 171 pass = getpassphrase(prompt); 172 173 err = smbfs_keychain_add((uid_t)-1, dom, usr, pass); 174 if (err) 175 errx(1, gettext("failed to add keychain entry")); 176 177 return (0); 178 } 179 180 181 void 182 logout_usage(void) 183 { 184 printf(gettext("usage: smbutil logout [[domain/]user]\n")); 185 printf(gettext(" smbutil logout [user[@domain]]\n")); 186 printf(gettext(" smbutil logout -a\n")); 187 exit(1); 188 } 189 190 int 191 cmd_logout(int argc, char *argv[]) 192 { 193 char *dom, *usr; 194 int err, opt; 195 196 while ((opt = getopt(argc, argv, "a")) != EOF) { 197 switch (opt) { 198 199 case 'a': /* smbutil logout -a */ 200 if (optind != argc) 201 logout_usage(); 202 err = smbfs_keychain_del_owner(); 203 if (err) 204 errx(1, 205 gettext("failed to delete keychain entries")); 206 return (0); 207 208 default: 209 logout_usage(); 210 break; 211 } 212 } 213 214 /* This part is like login. */ 215 dom = usr = NULL; 216 if (optind < argc) { 217 strcpy(tmp_arg, argv[optind]); 218 err = smbfs_parse_domuser(tmp_arg, &dom, &usr); 219 if (err) 220 errx(1, gettext("failed to parse %s"), argv[optind]); 221 optind++; 222 } 223 if (optind != argc) 224 logout_usage(); 225 226 if (dom == NULL || usr == NULL) { 227 err = smbfs_default_dom_usr(NULL, NULL, 228 def_dom, sizeof (def_dom), 229 def_usr, sizeof (def_usr)); 230 if (err) 231 errx(1, gettext("failed to get defaults")); 232 } 233 if (dom == NULL) 234 dom = def_dom; 235 else 236 nls_str_upper(dom, dom); 237 if (usr == NULL) 238 usr = def_usr; 239 240 err = smbfs_keychain_del((uid_t)-1, dom, usr); 241 if (err) 242 errx(1, gettext("failed to delete keychain entry")); 243 244 return (0); 245 } 246 247 248 void 249 logoutall_usage(void) 250 { 251 printf(gettext("usage: smbutil logoutall\n")); 252 exit(1); 253 } 254 255 int 256 cmd_logoutall(int argc, char *argv[]) 257 { 258 int err; 259 260 if (optind != argc) 261 logoutall_usage(); 262 263 err = smbfs_keychain_del_everyone(); 264 if (err == EPERM) { 265 errx(1, 266 gettext("You must have super-user privileges to use this sub-command\n")); 267 } 268 if (err) { 269 errx(1, gettext("Failed to delete all keychain entries: %s\n"), 270 smb_strerror(err)); 271 } 272 273 return (0); 274 } 275