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 #include <sys/param.h> 36 #include <sys/errno.h> 37 #include <sys/stat.h> 38 39 #include <stdio.h> 40 #include <stdlib.h> 41 #include <strings.h> 42 #include <unistd.h> 43 #include <err.h> 44 #include <libintl.h> 45 46 #include <netsmb/smb_lib.h> 47 #include <netsmb/smb_keychain.h> 48 49 #include "common.h" 50 51 /* defaults */ 52 static char def_dom[256]; 53 static char def_usr[256]; 54 static char tmp_arg[256]; 55 56 57 /* 58 * Parse the string: domuser, which may be any of: 59 * "user@domain" or "domain/user" or "domain\\user" 60 * and return pointers to the domain and user parts. 61 * Modifies the string domuser in-place. Returned 62 * string pointers are within the string domusr. 63 */ 64 int 65 smbfs_parse_domuser(char *domuser, char **dom, char **usr) 66 { 67 const char sep[] = "@/\\"; 68 char sc, *p, *s1, *s2; 69 70 p = strpbrk(domuser, sep); 71 if (p == NULL) { 72 /* No separators - whole string is the user. */ 73 *dom = NULL; 74 *usr = domuser; 75 return (0); 76 } 77 78 /* Have two strings. */ 79 s1 = domuser; 80 sc = *p; /* Save the sep. char */ 81 *p++ = '\0'; /* zap it */ 82 s2 = p; 83 84 /* Enforce just one separator */ 85 p = strpbrk(s2, sep); 86 if (p) 87 return (-1); 88 89 /* 90 * Now, which order are they? 91 * "user@domain" or "domain/user" 92 */ 93 if (sc == '@') { 94 *usr = s1; 95 *dom = s2; 96 } else { 97 *dom = s1; 98 *usr = s2; 99 } 100 101 return (0); 102 } 103 104 void 105 login_usage(void) 106 { 107 printf(gettext("usage: smbutil login [-c] [[domain/]user]\n")); 108 printf(gettext(" smbutil login [-c] [user[@domain]]\n")); 109 exit(1); 110 } 111 112 int 113 cmd_login(int argc, char *argv[]) 114 { 115 static char prompt[64]; 116 char *dom, *usr, *pass; 117 int err, opt; 118 int check = 0; 119 120 while ((opt = getopt(argc, argv, "c")) != EOF) { 121 switch (opt) { 122 123 case 'c': /* smbutil login -c ... */ 124 check = 1; 125 break; 126 127 default: 128 login_usage(); 129 break; 130 } 131 } 132 133 dom = usr = NULL; 134 if (optind < argc) { 135 strcpy(tmp_arg, argv[optind]); 136 err = smbfs_parse_domuser(tmp_arg, &dom, &usr); 137 if (err) 138 errx(1, gettext("failed to parse %s"), argv[optind]); 139 optind++; 140 } 141 if (optind != argc) 142 login_usage(); 143 144 if (dom == NULL || usr == NULL) { 145 err = smbfs_default_dom_usr(NULL, NULL, 146 def_dom, sizeof (def_dom), 147 def_usr, sizeof (def_usr)); 148 if (err) 149 errx(1, gettext("failed to get defaults")); 150 } 151 if (dom == NULL) 152 dom = def_dom; 153 else 154 nls_str_upper(dom, dom); 155 if (usr == NULL) 156 usr = def_usr; 157 158 if (check) { 159 err = smbfs_keychain_chk(dom, usr); 160 if (!err) 161 printf(gettext("Keychain entry exists.\n")); 162 else 163 printf(gettext("Keychain entry not found.\n")); 164 return (0); 165 } 166 167 snprintf(prompt, sizeof (prompt), 168 gettext("Password for %s/%s:"), dom, usr); 169 pass = getpassphrase(prompt); 170 171 err = smbfs_keychain_add((uid_t)-1, dom, usr, pass); 172 if (err) 173 errx(1, gettext("failed to add keychain entry")); 174 175 return (0); 176 } 177 178 179 void 180 logout_usage(void) 181 { 182 printf(gettext("usage: smbutil logout [[domain/]user]\n")); 183 printf(gettext(" smbutil logout [user[@domain]]\n")); 184 printf(gettext(" smbutil logout -a\n")); 185 exit(1); 186 } 187 188 int 189 cmd_logout(int argc, char *argv[]) 190 { 191 char *dom, *usr; 192 int err, opt; 193 194 while ((opt = getopt(argc, argv, "a")) != EOF) { 195 switch (opt) { 196 197 case 'a': /* smbutil logout -a */ 198 if (optind != argc) 199 logout_usage(); 200 err = smbfs_keychain_del_owner(); 201 if (err) 202 errx(1, 203 gettext("failed to delete keychain entries")); 204 return (0); 205 206 default: 207 logout_usage(); 208 break; 209 } 210 } 211 212 /* This part is like login. */ 213 dom = usr = NULL; 214 if (optind < argc) { 215 strcpy(tmp_arg, argv[optind]); 216 err = smbfs_parse_domuser(tmp_arg, &dom, &usr); 217 if (err) 218 errx(1, gettext("failed to parse %s"), argv[optind]); 219 optind++; 220 } 221 if (optind != argc) 222 logout_usage(); 223 224 if (dom == NULL || usr == NULL) { 225 err = smbfs_default_dom_usr(NULL, NULL, 226 def_dom, sizeof (def_dom), 227 def_usr, sizeof (def_usr)); 228 if (err) 229 errx(1, gettext("failed to get defaults")); 230 } 231 if (dom == NULL) 232 dom = def_dom; 233 else 234 nls_str_upper(dom, dom); 235 if (usr == NULL) 236 usr = def_usr; 237 238 err = smbfs_keychain_del((uid_t)-1, dom, usr); 239 if (err) 240 errx(1, gettext("failed to delete keychain entry")); 241 242 return (0); 243 } 244 245 246 void 247 logoutall_usage(void) 248 { 249 printf(gettext("usage: smbutil logoutall\n")); 250 exit(1); 251 } 252 253 int 254 cmd_logoutall(int argc, char *argv[]) 255 { 256 int err; 257 258 if (optind != argc) 259 logoutall_usage(); 260 261 err = smbfs_keychain_del_everyone(); 262 if (err == EPERM) { 263 errx(1, 264 gettext("You must have super-user privileges to use this sub-command\n")); 265 } 266 if (err) { 267 errx(1, gettext("Failed to delete all keychain entries: %s\n"), 268 smb_strerror(err)); 269 } 270 271 return (0); 272 } 273