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