15331Samw /* 25331Samw * CDDL HEADER START 35331Samw * 45331Samw * The contents of this file are subject to the terms of the 55331Samw * Common Development and Distribution License (the "License"). 65331Samw * You may not use this file except in compliance with the License. 75331Samw * 85331Samw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 95331Samw * or http://www.opensolaris.org/os/licensing. 105331Samw * See the License for the specific language governing permissions 115331Samw * and limitations under the License. 125331Samw * 135331Samw * When distributing Covered Code, include this CDDL HEADER in each 145331Samw * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 155331Samw * If applicable, add the following below this CDDL HEADER, with the 165331Samw * fields enclosed by brackets "[]" replaced with your own identifying 175331Samw * information: Portions Copyright [yyyy] [name of copyright owner] 185331Samw * 195331Samw * CDDL HEADER END 205331Samw */ 215331Samw /* 22*11633SJoyce.McIntosh@Sun.COM * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 235331Samw * Use is subject to license terms. 245331Samw */ 255331Samw 265331Samw /* 275331Samw * This module contains smbadm CLI which offers smb configuration 285331Samw * functionalities. 295331Samw */ 308334SJose.Borrego@Sun.COM #include <errno.h> 318334SJose.Borrego@Sun.COM #include <err.h> 328334SJose.Borrego@Sun.COM #include <ctype.h> 335331Samw #include <stdlib.h> 34*11633SJoyce.McIntosh@Sun.COM #include <unistd.h> 355331Samw #include <stdio.h> 365331Samw #include <syslog.h> 375331Samw #include <strings.h> 385331Samw #include <limits.h> 395331Samw #include <getopt.h> 405331Samw #include <libintl.h> 415331Samw #include <zone.h> 42*11633SJoyce.McIntosh@Sun.COM #include <pwd.h> 435331Samw #include <grp.h> 445331Samw #include <libgen.h> 457348SJose.Borrego@Sun.COM #include <netinet/in.h> 46*11633SJoyce.McIntosh@Sun.COM #include <auth_attr.h> 47*11633SJoyce.McIntosh@Sun.COM #include <locale.h> 485331Samw #include <smbsrv/libsmb.h> 495331Samw 50*11633SJoyce.McIntosh@Sun.COM #if !defined(TEXT_DOMAIN) 51*11633SJoyce.McIntosh@Sun.COM #define TEXT_DOMAIN "SYS_TEST" 52*11633SJoyce.McIntosh@Sun.COM #endif 53*11633SJoyce.McIntosh@Sun.COM 545331Samw typedef enum { 555331Samw HELP_ADD_MEMBER, 565331Samw HELP_CREATE, 575331Samw HELP_DELETE, 585331Samw HELP_DEL_MEMBER, 595331Samw HELP_GET, 605331Samw HELP_JOIN, 615331Samw HELP_LIST, 625331Samw HELP_RENAME, 635331Samw HELP_SET, 645331Samw HELP_SHOW, 657052Samw HELP_USER_DISABLE, 667052Samw HELP_USER_ENABLE 675331Samw } smbadm_help_t; 685331Samw 69*11633SJoyce.McIntosh@Sun.COM #define SMBADM_CMDF_NONE 0x00 707052Samw #define SMBADM_CMDF_USER 0x01 717052Samw #define SMBADM_CMDF_GROUP 0x02 727052Samw #define SMBADM_CMDF_TYPEMASK 0x0F 736139Sjb150015 747348SJose.Borrego@Sun.COM #define SMBADM_ANSBUFSIZ 64 757348SJose.Borrego@Sun.COM 765331Samw typedef struct smbadm_cmdinfo { 775331Samw char *name; 785331Samw int (*func)(int, char **); 795331Samw smbadm_help_t usage; 806139Sjb150015 uint32_t flags; 81*11633SJoyce.McIntosh@Sun.COM char *auth; 825331Samw } smbadm_cmdinfo_t; 835331Samw 845331Samw smbadm_cmdinfo_t *curcmd; 855331Samw static char *progname; 865331Samw 87*11633SJoyce.McIntosh@Sun.COM #define SMBADM_ACTION_AUTH "solaris.smf.manage.smb" 88*11633SJoyce.McIntosh@Sun.COM #define SMBADM_VALUE_AUTH "solaris.smf.value.smb" 89*11633SJoyce.McIntosh@Sun.COM #define SMBADM_BASIC_AUTH "solaris.network.hosts.read" 90*11633SJoyce.McIntosh@Sun.COM 91*11633SJoyce.McIntosh@Sun.COM static boolean_t smbadm_checkauth(const char *); 92*11633SJoyce.McIntosh@Sun.COM 938334SJose.Borrego@Sun.COM static void smbadm_usage(boolean_t); 948334SJose.Borrego@Sun.COM static int smbadm_join_workgroup(const char *); 958334SJose.Borrego@Sun.COM static int smbadm_join_domain(const char *, const char *); 968334SJose.Borrego@Sun.COM static void smbadm_extract_domain(char *, char **, char **); 978334SJose.Borrego@Sun.COM 985331Samw static int smbadm_join(int, char **); 995331Samw static int smbadm_list(int, char **); 1005331Samw static int smbadm_group_create(int, char **); 1015331Samw static int smbadm_group_delete(int, char **); 1025331Samw static int smbadm_group_rename(int, char **); 1035331Samw static int smbadm_group_show(int, char **); 10411337SWilliam.Krier@Sun.COM static void smbadm_group_show_name(const char *, const char *); 1055331Samw static int smbadm_group_getprop(int, char **); 1065331Samw static int smbadm_group_setprop(int, char **); 1075331Samw static int smbadm_group_addmember(int, char **); 1085331Samw static int smbadm_group_delmember(int, char **); 1095331Samw static int smbadm_user_disable(int, char **); 1105331Samw static int smbadm_user_enable(int, char **); 1115331Samw 1125331Samw static smbadm_cmdinfo_t smbadm_cmdtable[] = 1135331Samw { 1146139Sjb150015 { "add-member", smbadm_group_addmember, HELP_ADD_MEMBER, 115*11633SJoyce.McIntosh@Sun.COM SMBADM_CMDF_GROUP, SMBADM_ACTION_AUTH }, 1166139Sjb150015 { "create", smbadm_group_create, HELP_CREATE, 117*11633SJoyce.McIntosh@Sun.COM SMBADM_CMDF_GROUP, SMBADM_ACTION_AUTH }, 1186139Sjb150015 { "delete", smbadm_group_delete, HELP_DELETE, 119*11633SJoyce.McIntosh@Sun.COM SMBADM_CMDF_GROUP, SMBADM_ACTION_AUTH }, 1207052Samw { "disable-user", smbadm_user_disable, HELP_USER_DISABLE, 121*11633SJoyce.McIntosh@Sun.COM SMBADM_CMDF_USER, SMBADM_ACTION_AUTH }, 1227052Samw { "enable-user", smbadm_user_enable, HELP_USER_ENABLE, 123*11633SJoyce.McIntosh@Sun.COM SMBADM_CMDF_USER, SMBADM_ACTION_AUTH }, 1246139Sjb150015 { "get", smbadm_group_getprop, HELP_GET, 125*11633SJoyce.McIntosh@Sun.COM SMBADM_CMDF_GROUP, SMBADM_ACTION_AUTH }, 126*11633SJoyce.McIntosh@Sun.COM { "join", smbadm_join, HELP_JOIN, 127*11633SJoyce.McIntosh@Sun.COM SMBADM_CMDF_NONE, SMBADM_VALUE_AUTH }, 128*11633SJoyce.McIntosh@Sun.COM { "list", smbadm_list, HELP_LIST, 129*11633SJoyce.McIntosh@Sun.COM SMBADM_CMDF_NONE, SMBADM_BASIC_AUTH }, 1306139Sjb150015 { "remove-member", smbadm_group_delmember, HELP_DEL_MEMBER, 131*11633SJoyce.McIntosh@Sun.COM SMBADM_CMDF_GROUP, SMBADM_ACTION_AUTH }, 1326139Sjb150015 { "rename", smbadm_group_rename, HELP_RENAME, 133*11633SJoyce.McIntosh@Sun.COM SMBADM_CMDF_GROUP, SMBADM_ACTION_AUTH }, 1346139Sjb150015 { "set", smbadm_group_setprop, HELP_SET, 135*11633SJoyce.McIntosh@Sun.COM SMBADM_CMDF_GROUP, SMBADM_ACTION_AUTH }, 1366139Sjb150015 { "show", smbadm_group_show, HELP_SHOW, 137*11633SJoyce.McIntosh@Sun.COM SMBADM_CMDF_GROUP, SMBADM_ACTION_AUTH }, 1385331Samw }; 1395331Samw 1405331Samw #define SMBADM_NCMD (sizeof (smbadm_cmdtable) / sizeof (smbadm_cmdtable[0])) 1415331Samw 1425331Samw typedef struct smbadm_prop { 1435331Samw char *p_name; 1445331Samw char *p_value; 1455331Samw } smbadm_prop_t; 1465331Samw 1475331Samw typedef struct smbadm_prop_handle { 1485331Samw char *p_name; 1495331Samw char *p_dispvalue; 1505331Samw int (*p_setfn)(char *, smbadm_prop_t *); 1515331Samw int (*p_getfn)(char *, smbadm_prop_t *); 1525331Samw boolean_t (*p_chkfn)(smbadm_prop_t *); 1535331Samw } smbadm_prop_handle_t; 1545331Samw 1555331Samw static boolean_t smbadm_prop_validate(smbadm_prop_t *prop, boolean_t chkval); 1565331Samw static int smbadm_prop_parse(char *arg, smbadm_prop_t *prop); 1575331Samw static smbadm_prop_handle_t *smbadm_prop_gethandle(char *pname); 1585331Samw 1595331Samw static boolean_t smbadm_chkprop_priv(smbadm_prop_t *prop); 1605331Samw static int smbadm_setprop_tkowner(char *gname, smbadm_prop_t *prop); 1615331Samw static int smbadm_getprop_tkowner(char *gname, smbadm_prop_t *prop); 1625331Samw static int smbadm_setprop_backup(char *gname, smbadm_prop_t *prop); 1635331Samw static int smbadm_getprop_backup(char *gname, smbadm_prop_t *prop); 1645331Samw static int smbadm_setprop_restore(char *gname, smbadm_prop_t *prop); 1655331Samw static int smbadm_getprop_restore(char *gname, smbadm_prop_t *prop); 1665331Samw static int smbadm_setprop_desc(char *gname, smbadm_prop_t *prop); 1675331Samw static int smbadm_getprop_desc(char *gname, smbadm_prop_t *prop); 1685331Samw 1695331Samw static smbadm_prop_handle_t smbadm_ptable[] = { 1705331Samw {"backup", "on | off", smbadm_setprop_backup, 1715331Samw smbadm_getprop_backup, smbadm_chkprop_priv }, 1725331Samw {"restore", "on | off", smbadm_setprop_restore, 1735331Samw smbadm_getprop_restore, smbadm_chkprop_priv }, 1745331Samw {"take-ownership", "on | off", smbadm_setprop_tkowner, 1755331Samw smbadm_getprop_tkowner, smbadm_chkprop_priv }, 1765331Samw {"description", "<string>", smbadm_setprop_desc, 1775331Samw smbadm_getprop_desc, NULL }, 1785331Samw }; 1795331Samw 1807052Samw static int smbadm_init(void); 1817052Samw static void smbadm_fini(void); 1825331Samw static const char *smbadm_pwd_strerror(int error); 1835331Samw 1845331Samw /* 1855331Samw * Number of supported properties 1865331Samw */ 1875331Samw #define SMBADM_NPROP (sizeof (smbadm_ptable) / sizeof (smbadm_ptable[0])) 1885331Samw 1895331Samw static void 1905331Samw smbadm_cmdusage(FILE *fp, smbadm_cmdinfo_t *cmd) 1915331Samw { 1925331Samw switch (cmd->usage) { 1935331Samw case HELP_ADD_MEMBER: 1945331Samw (void) fprintf(fp, 1955331Samw gettext("\t%s -m member [[-m member] ...] group\n"), 1965331Samw cmd->name); 1975331Samw return; 1985331Samw 1995331Samw case HELP_CREATE: 2005331Samw (void) fprintf(fp, gettext("\t%s [-d description] group\n"), 2015331Samw cmd->name); 2025331Samw return; 2035331Samw 2045331Samw case HELP_DELETE: 2055331Samw (void) fprintf(fp, gettext("\t%s group\n"), cmd->name); 2065331Samw return; 2075331Samw 2087052Samw case HELP_USER_DISABLE: 2097052Samw case HELP_USER_ENABLE: 2105331Samw (void) fprintf(fp, gettext("\t%s user\n"), cmd->name); 2115331Samw return; 2125331Samw 2135331Samw case HELP_GET: 2145331Samw (void) fprintf(fp, gettext("\t%s [[-p property] ...] group\n"), 2155331Samw cmd->name); 2165331Samw return; 2175331Samw 2185331Samw case HELP_JOIN: 2195331Samw (void) fprintf(fp, gettext("\t%s -u username domain\n" 2205331Samw "\t%s -w workgroup\n"), cmd->name, cmd->name); 2215331Samw return; 2225331Samw 2235331Samw case HELP_LIST: 2245331Samw (void) fprintf(fp, gettext("\t%s\n"), cmd->name); 2258474SJose.Borrego@Sun.COM (void) fprintf(fp, 2268474SJose.Borrego@Sun.COM gettext("\t\t[*] primary domain\n")); 2278474SJose.Borrego@Sun.COM (void) fprintf(fp, gettext("\t\t[.] local domain\n")); 2288474SJose.Borrego@Sun.COM (void) fprintf(fp, gettext("\t\t[-] other domains\n")); 2298474SJose.Borrego@Sun.COM (void) fprintf(fp, 2308474SJose.Borrego@Sun.COM gettext("\t\t[+] selected domain controller\n")); 2315331Samw return; 2325331Samw 2335331Samw case HELP_DEL_MEMBER: 2345331Samw (void) fprintf(fp, 2355331Samw gettext("\t%s -m member [[-m member] ...] group\n"), 2365331Samw cmd->name); 2375331Samw return; 2385331Samw 2395331Samw case HELP_RENAME: 2405331Samw (void) fprintf(fp, gettext("\t%s group new-group\n"), 2415331Samw cmd->name); 2425331Samw return; 2435331Samw 2445331Samw case HELP_SET: 2455331Samw (void) fprintf(fp, gettext("\t%s -p property=value " 2465331Samw "[[-p property=value] ...] group\n"), cmd->name); 2475331Samw return; 2485331Samw 2495331Samw case HELP_SHOW: 2505331Samw (void) fprintf(fp, gettext("\t%s [-m] [-p] [group]\n"), 2515331Samw cmd->name); 2525331Samw return; 2535331Samw 2547052Samw default: 2557052Samw break; 2565331Samw } 2575331Samw 2585331Samw abort(); 2595331Samw /* NOTREACHED */ 2605331Samw } 2615331Samw 2625331Samw static void 2635331Samw smbadm_usage(boolean_t requested) 2645331Samw { 2655331Samw FILE *fp = requested ? stdout : stderr; 2665331Samw boolean_t show_props = B_FALSE; 2675331Samw int i; 2685331Samw 2695331Samw if (curcmd == NULL) { 2705331Samw (void) fprintf(fp, 2715331Samw gettext("usage: %s [-h | <command> [options]]\n"), 2725331Samw progname); 2735331Samw (void) fprintf(fp, 2745331Samw gettext("where 'command' is one of the following:\n\n")); 2755331Samw 2765331Samw for (i = 0; i < SMBADM_NCMD; i++) 2775331Samw smbadm_cmdusage(fp, &smbadm_cmdtable[i]); 2785331Samw 2795331Samw (void) fprintf(fp, 2805331Samw gettext("\nFor property list, run %s %s|%s\n"), 2815331Samw progname, "get", "set"); 2825331Samw 2835331Samw exit(requested ? 0 : 2); 2845331Samw } 2855331Samw 2865331Samw (void) fprintf(fp, gettext("usage:\n")); 2875331Samw smbadm_cmdusage(fp, curcmd); 2885331Samw 2895331Samw if (strcmp(curcmd->name, "get") == 0 || 2905331Samw strcmp(curcmd->name, "set") == 0) 2915331Samw show_props = B_TRUE; 2925331Samw 2935331Samw if (show_props) { 2945331Samw (void) fprintf(fp, 2955331Samw gettext("\nThe following properties are supported:\n")); 2965331Samw 2975331Samw (void) fprintf(fp, "\n\t%-16s %s\n\n", 2985331Samw "PROPERTY", "VALUES"); 2995331Samw 3005331Samw for (i = 0; i < SMBADM_NPROP; i++) { 3015331Samw (void) fprintf(fp, "\t%-16s %s\n", 3025331Samw smbadm_ptable[i].p_name, 3035331Samw smbadm_ptable[i].p_dispvalue); 3045331Samw } 3055331Samw } 3065331Samw 3075331Samw exit(requested ? 0 : 2); 3085331Samw } 3095331Samw 3105331Samw /* 3117348SJose.Borrego@Sun.COM * smbadm_strcasecmplist 3127348SJose.Borrego@Sun.COM * 3137348SJose.Borrego@Sun.COM * Find a string 's' within a list of strings. 3147348SJose.Borrego@Sun.COM * 3157348SJose.Borrego@Sun.COM * Returns the index of the matching string or -1 if there is no match. 3167348SJose.Borrego@Sun.COM */ 3177348SJose.Borrego@Sun.COM static int 3187348SJose.Borrego@Sun.COM smbadm_strcasecmplist(const char *s, ...) 3197348SJose.Borrego@Sun.COM { 3207348SJose.Borrego@Sun.COM va_list ap; 3217348SJose.Borrego@Sun.COM char *p; 3227348SJose.Borrego@Sun.COM int ndx; 3237348SJose.Borrego@Sun.COM 3247348SJose.Borrego@Sun.COM va_start(ap, s); 3257348SJose.Borrego@Sun.COM 3267348SJose.Borrego@Sun.COM for (ndx = 0; ((p = va_arg(ap, char *)) != NULL); ++ndx) { 3277348SJose.Borrego@Sun.COM if (strcasecmp(s, p) == 0) { 3287348SJose.Borrego@Sun.COM va_end(ap); 3297348SJose.Borrego@Sun.COM return (ndx); 3307348SJose.Borrego@Sun.COM } 3317348SJose.Borrego@Sun.COM } 3327348SJose.Borrego@Sun.COM 3337348SJose.Borrego@Sun.COM va_end(ap); 3347348SJose.Borrego@Sun.COM return (-1); 3357348SJose.Borrego@Sun.COM } 3367348SJose.Borrego@Sun.COM 3377348SJose.Borrego@Sun.COM /* 3387348SJose.Borrego@Sun.COM * smbadm_answer_prompt 3397348SJose.Borrego@Sun.COM * 3407348SJose.Borrego@Sun.COM * Prompt for the answer to a question. A default response must be 3417348SJose.Borrego@Sun.COM * specified, which will be used if the user presses <enter> without 3427348SJose.Borrego@Sun.COM * answering the question. 3437348SJose.Borrego@Sun.COM */ 3447348SJose.Borrego@Sun.COM static int 3457348SJose.Borrego@Sun.COM smbadm_answer_prompt(const char *prompt, char *answer, const char *dflt) 3467348SJose.Borrego@Sun.COM { 3477348SJose.Borrego@Sun.COM char buf[SMBADM_ANSBUFSIZ]; 3487348SJose.Borrego@Sun.COM char *p; 3497348SJose.Borrego@Sun.COM 3507348SJose.Borrego@Sun.COM (void) printf(gettext("%s [%s]: "), prompt, dflt); 3517348SJose.Borrego@Sun.COM 3527348SJose.Borrego@Sun.COM if (fgets(buf, SMBADM_ANSBUFSIZ, stdin) == NULL) 3537348SJose.Borrego@Sun.COM return (-1); 3547348SJose.Borrego@Sun.COM 3557348SJose.Borrego@Sun.COM if ((p = strchr(buf, '\n')) != NULL) 3567348SJose.Borrego@Sun.COM *p = '\0'; 3577348SJose.Borrego@Sun.COM 3587348SJose.Borrego@Sun.COM if (*buf == '\0') 3597348SJose.Borrego@Sun.COM (void) strlcpy(answer, dflt, SMBADM_ANSBUFSIZ); 3607348SJose.Borrego@Sun.COM else 3617348SJose.Borrego@Sun.COM (void) strlcpy(answer, buf, SMBADM_ANSBUFSIZ); 3627348SJose.Borrego@Sun.COM 3637348SJose.Borrego@Sun.COM return (0); 3647348SJose.Borrego@Sun.COM } 3657348SJose.Borrego@Sun.COM 3667348SJose.Borrego@Sun.COM /* 3677348SJose.Borrego@Sun.COM * smbadm_confirm 3687348SJose.Borrego@Sun.COM * 3697348SJose.Borrego@Sun.COM * Ask a question that requires a yes/no answer. 3707348SJose.Borrego@Sun.COM * A default response must be specified. 3717348SJose.Borrego@Sun.COM */ 3727348SJose.Borrego@Sun.COM static boolean_t 3737348SJose.Borrego@Sun.COM smbadm_confirm(const char *prompt, const char *dflt) 3747348SJose.Borrego@Sun.COM { 3757348SJose.Borrego@Sun.COM char buf[SMBADM_ANSBUFSIZ]; 3767348SJose.Borrego@Sun.COM 3777348SJose.Borrego@Sun.COM for (;;) { 3787348SJose.Borrego@Sun.COM if (smbadm_answer_prompt(prompt, buf, dflt) < 0) 3797348SJose.Borrego@Sun.COM return (B_FALSE); 3807348SJose.Borrego@Sun.COM 3817348SJose.Borrego@Sun.COM if (smbadm_strcasecmplist(buf, "n", "no", 0) >= 0) 3827348SJose.Borrego@Sun.COM return (B_FALSE); 3837348SJose.Borrego@Sun.COM 3847348SJose.Borrego@Sun.COM if (smbadm_strcasecmplist(buf, "y", "yes", 0) >= 0) 3857348SJose.Borrego@Sun.COM return (B_TRUE); 3867348SJose.Borrego@Sun.COM 3877348SJose.Borrego@Sun.COM (void) printf(gettext("Please answer yes or no.\n")); 3887348SJose.Borrego@Sun.COM } 3897348SJose.Borrego@Sun.COM } 3907348SJose.Borrego@Sun.COM 3917348SJose.Borrego@Sun.COM static boolean_t 3928334SJose.Borrego@Sun.COM smbadm_join_prompt(const char *domain) 3937348SJose.Borrego@Sun.COM { 3948334SJose.Borrego@Sun.COM (void) printf(gettext("After joining %s the smb service will be " 3958334SJose.Borrego@Sun.COM "restarted automatically.\n"), domain); 3967348SJose.Borrego@Sun.COM 3978334SJose.Borrego@Sun.COM return (smbadm_confirm("Would you like to continue?", "no")); 3988334SJose.Borrego@Sun.COM } 3997348SJose.Borrego@Sun.COM 4008334SJose.Borrego@Sun.COM static void 4018334SJose.Borrego@Sun.COM smbadm_restart_service(void) 4028334SJose.Borrego@Sun.COM { 4038334SJose.Borrego@Sun.COM if (smb_smf_restart_service() != 0) { 4048334SJose.Borrego@Sun.COM (void) fprintf(stderr, 4058334SJose.Borrego@Sun.COM gettext("Unable to restart smb service. " 4068334SJose.Borrego@Sun.COM "Run 'svcs -xv smb/server' for more information.")); 4077348SJose.Borrego@Sun.COM } 4087348SJose.Borrego@Sun.COM } 4097348SJose.Borrego@Sun.COM 4107348SJose.Borrego@Sun.COM /* 4115331Samw * smbadm_join 4125331Samw * 4138334SJose.Borrego@Sun.COM * Join a domain or workgroup. 4148334SJose.Borrego@Sun.COM * 4158334SJose.Borrego@Sun.COM * When joining a domain, we may receive the username, password and 4168334SJose.Borrego@Sun.COM * domain name in any of the following combinations. Note that the 4178334SJose.Borrego@Sun.COM * password is optional on the command line: if it is not provided, 4188334SJose.Borrego@Sun.COM * we will prompt for it later. 4198334SJose.Borrego@Sun.COM * 4208334SJose.Borrego@Sun.COM * username+password domain 4218334SJose.Borrego@Sun.COM * domain\username+password 4228334SJose.Borrego@Sun.COM * domain/username+password 4238334SJose.Borrego@Sun.COM * username@domain 4248334SJose.Borrego@Sun.COM * 4258334SJose.Borrego@Sun.COM * We allow domain\name+password or domain/name+password but not 4268334SJose.Borrego@Sun.COM * name+password@domain because @ is a valid password character. 4278334SJose.Borrego@Sun.COM * 4288334SJose.Borrego@Sun.COM * If the username and domain name are passed as separate command 4298334SJose.Borrego@Sun.COM * line arguments, we process them directly. Otherwise we separate 4308334SJose.Borrego@Sun.COM * them and continue as if they were separate command line arguments. 4315331Samw */ 4325331Samw static int 4335331Samw smbadm_join(int argc, char **argv) 4345331Samw { 4358334SJose.Borrego@Sun.COM char buf[MAXHOSTNAMELEN * 2]; 4368334SJose.Borrego@Sun.COM char *domain = NULL; 4378334SJose.Borrego@Sun.COM char *username = NULL; 4388334SJose.Borrego@Sun.COM uint32_t mode = 0; 4395331Samw char option; 4405331Samw 4415331Samw while ((option = getopt(argc, argv, "u:w:")) != -1) { 4425331Samw switch (option) { 4435331Samw case 'w': 4448334SJose.Borrego@Sun.COM if (mode != 0) { 4458334SJose.Borrego@Sun.COM (void) fprintf(stderr, 4468334SJose.Borrego@Sun.COM gettext("-u and -w must only appear " 4478334SJose.Borrego@Sun.COM "once and are mutually exclusive\n")); 4488334SJose.Borrego@Sun.COM smbadm_usage(B_FALSE); 4498334SJose.Borrego@Sun.COM } 4508334SJose.Borrego@Sun.COM 4518334SJose.Borrego@Sun.COM mode = SMB_SECMODE_WORKGRP; 4528334SJose.Borrego@Sun.COM domain = optarg; 4535331Samw break; 4545331Samw 4555331Samw case 'u': 4568334SJose.Borrego@Sun.COM if (mode != 0) { 4578334SJose.Borrego@Sun.COM (void) fprintf(stderr, 4588334SJose.Borrego@Sun.COM gettext("-u and -w must only appear " 4598334SJose.Borrego@Sun.COM "once and are mutually exclusive\n")); 4608334SJose.Borrego@Sun.COM smbadm_usage(B_FALSE); 4618334SJose.Borrego@Sun.COM } 4628334SJose.Borrego@Sun.COM 4638334SJose.Borrego@Sun.COM mode = SMB_SECMODE_DOMAIN; 4648334SJose.Borrego@Sun.COM username = optarg; 4658334SJose.Borrego@Sun.COM 4668334SJose.Borrego@Sun.COM if ((domain = argv[optind]) == NULL) { 4678334SJose.Borrego@Sun.COM /* 4688334SJose.Borrego@Sun.COM * The domain was not specified as a separate 4698334SJose.Borrego@Sun.COM * argument, check for the combination forms. 4708334SJose.Borrego@Sun.COM */ 4718334SJose.Borrego@Sun.COM (void) strlcpy(buf, username, sizeof (buf)); 4728334SJose.Borrego@Sun.COM smbadm_extract_domain(buf, &username, &domain); 4738334SJose.Borrego@Sun.COM } 4748334SJose.Borrego@Sun.COM 4758334SJose.Borrego@Sun.COM if ((username == NULL) || (*username == '\0')) { 4768334SJose.Borrego@Sun.COM (void) fprintf(stderr, 4778334SJose.Borrego@Sun.COM gettext("missing username\n")); 4788334SJose.Borrego@Sun.COM smbadm_usage(B_FALSE); 4798334SJose.Borrego@Sun.COM } 4805331Samw break; 4815331Samw 4825331Samw default: 4835331Samw smbadm_usage(B_FALSE); 4848334SJose.Borrego@Sun.COM break; 4855331Samw } 4865331Samw } 4875331Samw 4888334SJose.Borrego@Sun.COM if ((domain == NULL) || (*domain == '\0')) { 4898334SJose.Borrego@Sun.COM (void) fprintf(stderr, gettext("missing %s name\n"), 4908334SJose.Borrego@Sun.COM (mode == SMB_SECMODE_WORKGRP) ? "workgroup" : "domain"); 4915331Samw smbadm_usage(B_FALSE); 4925331Samw } 4935331Samw 4948334SJose.Borrego@Sun.COM if (mode == SMB_SECMODE_WORKGRP) 4958334SJose.Borrego@Sun.COM return (smbadm_join_workgroup(domain)); 4968334SJose.Borrego@Sun.COM else 4978334SJose.Borrego@Sun.COM return (smbadm_join_domain(domain, username)); 4988334SJose.Borrego@Sun.COM } 4995331Samw 5008334SJose.Borrego@Sun.COM /* 5018334SJose.Borrego@Sun.COM * Workgroups comprise a collection of standalone, independently administered 5028334SJose.Borrego@Sun.COM * computers that use a common workgroup name. This is a peer-to-peer model 5038334SJose.Borrego@Sun.COM * with no formal membership mechanism. 5048334SJose.Borrego@Sun.COM */ 5058334SJose.Borrego@Sun.COM static int 5068334SJose.Borrego@Sun.COM smbadm_join_workgroup(const char *workgroup) 5078334SJose.Borrego@Sun.COM { 5088334SJose.Borrego@Sun.COM smb_joininfo_t jdi; 5098334SJose.Borrego@Sun.COM uint32_t status; 5105331Samw 5118334SJose.Borrego@Sun.COM bzero(&jdi, sizeof (jdi)); 5128334SJose.Borrego@Sun.COM jdi.mode = SMB_SECMODE_WORKGRP; 5138334SJose.Borrego@Sun.COM (void) strlcpy(jdi.domain_name, workgroup, sizeof (jdi.domain_name)); 5148334SJose.Borrego@Sun.COM (void) strtrim(jdi.domain_name, " \t\n"); 5158334SJose.Borrego@Sun.COM 51611337SWilliam.Krier@Sun.COM if (smb_name_validate_workgroup(jdi.domain_name) != ERROR_SUCCESS) { 5178334SJose.Borrego@Sun.COM (void) fprintf(stderr, gettext("workgroup name is invalid\n")); 5185331Samw smbadm_usage(B_FALSE); 5195331Samw } 5205331Samw 5218334SJose.Borrego@Sun.COM if (!smbadm_join_prompt(jdi.domain_name)) 5228334SJose.Borrego@Sun.COM return (0); 5237348SJose.Borrego@Sun.COM 5248334SJose.Borrego@Sun.COM if ((status = smb_join(&jdi)) != NT_STATUS_SUCCESS) { 5258334SJose.Borrego@Sun.COM (void) fprintf(stderr, gettext("failed to join %s: %s\n"), 5265331Samw jdi.domain_name, xlate_nt_status(status)); 5275331Samw return (1); 5285331Samw } 5295331Samw 5308334SJose.Borrego@Sun.COM (void) printf(gettext("Successfully joined %s\n"), jdi.domain_name); 5318334SJose.Borrego@Sun.COM smbadm_restart_service(); 5328334SJose.Borrego@Sun.COM return (0); 5338334SJose.Borrego@Sun.COM } 5348334SJose.Borrego@Sun.COM 5358334SJose.Borrego@Sun.COM /* 5368334SJose.Borrego@Sun.COM * Domains comprise a centrally administered group of computers and accounts 5378334SJose.Borrego@Sun.COM * that share a common security and administration policy and database. 5388334SJose.Borrego@Sun.COM * Computers must join a domain and become domain members, which requires 5398334SJose.Borrego@Sun.COM * an administrator level account name. 5408334SJose.Borrego@Sun.COM * 5418334SJose.Borrego@Sun.COM * The '+' character is invalid within a username. We allow the password 5428334SJose.Borrego@Sun.COM * to be appended to the username using '+' as a scripting convenience. 5438334SJose.Borrego@Sun.COM */ 5448334SJose.Borrego@Sun.COM static int 5458334SJose.Borrego@Sun.COM smbadm_join_domain(const char *domain, const char *username) 5468334SJose.Borrego@Sun.COM { 5478334SJose.Borrego@Sun.COM smb_joininfo_t jdi; 5488334SJose.Borrego@Sun.COM uint32_t status; 5498334SJose.Borrego@Sun.COM char *prompt; 5508334SJose.Borrego@Sun.COM char *p; 5518334SJose.Borrego@Sun.COM int len; 5528334SJose.Borrego@Sun.COM 5538334SJose.Borrego@Sun.COM bzero(&jdi, sizeof (jdi)); 5548334SJose.Borrego@Sun.COM jdi.mode = SMB_SECMODE_DOMAIN; 5558334SJose.Borrego@Sun.COM (void) strlcpy(jdi.domain_name, domain, sizeof (jdi.domain_name)); 5568334SJose.Borrego@Sun.COM (void) strtrim(jdi.domain_name, " \t\n"); 5578334SJose.Borrego@Sun.COM 55811337SWilliam.Krier@Sun.COM if (smb_name_validate_domain(jdi.domain_name) != ERROR_SUCCESS) { 5598334SJose.Borrego@Sun.COM (void) fprintf(stderr, gettext("domain name is invalid\n")); 5608334SJose.Borrego@Sun.COM smbadm_usage(B_FALSE); 5616139Sjb150015 } 5626139Sjb150015 5638334SJose.Borrego@Sun.COM if (!smbadm_join_prompt(jdi.domain_name)) 5648334SJose.Borrego@Sun.COM return (0); 5658334SJose.Borrego@Sun.COM 5668334SJose.Borrego@Sun.COM if ((p = strchr(username, '+')) != NULL) { 5678334SJose.Borrego@Sun.COM ++p; 5688334SJose.Borrego@Sun.COM 5698334SJose.Borrego@Sun.COM len = (int)(p - username); 5708334SJose.Borrego@Sun.COM if (len > sizeof (jdi.domain_name)) 5718334SJose.Borrego@Sun.COM len = sizeof (jdi.domain_name); 5727348SJose.Borrego@Sun.COM 5738334SJose.Borrego@Sun.COM (void) strlcpy(jdi.domain_username, username, len); 5748334SJose.Borrego@Sun.COM (void) strlcpy(jdi.domain_passwd, p, 5758334SJose.Borrego@Sun.COM sizeof (jdi.domain_passwd)); 5768334SJose.Borrego@Sun.COM } else { 5778334SJose.Borrego@Sun.COM (void) strlcpy(jdi.domain_username, username, 5788334SJose.Borrego@Sun.COM sizeof (jdi.domain_username)); 5798334SJose.Borrego@Sun.COM } 5808334SJose.Borrego@Sun.COM 58111337SWilliam.Krier@Sun.COM if (smb_name_validate_account(jdi.domain_username) != ERROR_SUCCESS) { 5828334SJose.Borrego@Sun.COM (void) fprintf(stderr, 5838334SJose.Borrego@Sun.COM gettext("username contains invalid characters\n")); 5848334SJose.Borrego@Sun.COM smbadm_usage(B_FALSE); 5858334SJose.Borrego@Sun.COM } 5868334SJose.Borrego@Sun.COM 5875331Samw if (*jdi.domain_passwd == '\0') { 5888334SJose.Borrego@Sun.COM prompt = gettext("Enter domain password: "); 5898334SJose.Borrego@Sun.COM 5908334SJose.Borrego@Sun.COM if ((p = getpassphrase(prompt)) == NULL) { 5915331Samw (void) fprintf(stderr, gettext("missing password\n")); 5925331Samw smbadm_usage(B_FALSE); 5935331Samw } 5945331Samw 5955331Samw (void) strlcpy(jdi.domain_passwd, p, 5965331Samw sizeof (jdi.domain_passwd)); 5975331Samw } 5985331Samw 5998334SJose.Borrego@Sun.COM (void) printf(gettext("Joining %s ... this may take a minute ...\n"), 6005331Samw jdi.domain_name); 6015331Samw 6025331Samw status = smb_join(&jdi); 6035331Samw 6045331Samw switch (status) { 6055331Samw case NT_STATUS_SUCCESS: 6068334SJose.Borrego@Sun.COM (void) printf(gettext("Successfully joined %s\n"), 6075331Samw jdi.domain_name); 6088334SJose.Borrego@Sun.COM bzero(&jdi, sizeof (jdi)); 6098334SJose.Borrego@Sun.COM smbadm_restart_service(); 6105331Samw return (0); 6115331Samw 6125331Samw case NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND: 6138334SJose.Borrego@Sun.COM (void) fprintf(stderr, 6148334SJose.Borrego@Sun.COM gettext("failed to find any domain controllers for %s\n"), 6155331Samw jdi.domain_name); 6168334SJose.Borrego@Sun.COM bzero(&jdi, sizeof (jdi)); 6178334SJose.Borrego@Sun.COM return (1); 6185331Samw 6195331Samw default: 6208334SJose.Borrego@Sun.COM (void) fprintf(stderr, gettext("failed to join %s: %s\n"), 6215331Samw jdi.domain_name, xlate_nt_status(status)); 6229021Samw@Sun.COM (void) fprintf(stderr, gettext("Please refer to the system log" 6239021Samw@Sun.COM " for more information.\n")); 6248334SJose.Borrego@Sun.COM bzero(&jdi, sizeof (jdi)); 6258334SJose.Borrego@Sun.COM return (1); 6268334SJose.Borrego@Sun.COM } 6278334SJose.Borrego@Sun.COM } 6288334SJose.Borrego@Sun.COM 6298334SJose.Borrego@Sun.COM /* 6308334SJose.Borrego@Sun.COM * We want to process the user and domain names as separate strings. 6318334SJose.Borrego@Sun.COM * Check for names of the forms below and separate the components as 6328334SJose.Borrego@Sun.COM * required. 6338334SJose.Borrego@Sun.COM * 6348334SJose.Borrego@Sun.COM * name@domain 6358334SJose.Borrego@Sun.COM * domain\name 6368334SJose.Borrego@Sun.COM * domain/name 6378334SJose.Borrego@Sun.COM * 6388334SJose.Borrego@Sun.COM * If we encounter any of the forms above in arg, the @, / or \ 6398334SJose.Borrego@Sun.COM * separator is replaced by \0 and the username and domain pointers 6408334SJose.Borrego@Sun.COM * are changed to point to the appropriate components (in arg). 6418334SJose.Borrego@Sun.COM * 6428334SJose.Borrego@Sun.COM * If none of the separators are encountered, the username and domain 6438334SJose.Borrego@Sun.COM * pointers remain unchanged. 6448334SJose.Borrego@Sun.COM */ 6458334SJose.Borrego@Sun.COM static void 6468334SJose.Borrego@Sun.COM smbadm_extract_domain(char *arg, char **username, char **domain) 6478334SJose.Borrego@Sun.COM { 6488334SJose.Borrego@Sun.COM char *p; 6498334SJose.Borrego@Sun.COM 6508334SJose.Borrego@Sun.COM if ((p = strpbrk(arg, "/\\@")) != NULL) { 6518334SJose.Borrego@Sun.COM if (*p == '@') { 6528334SJose.Borrego@Sun.COM *p = '\0'; 6538334SJose.Borrego@Sun.COM ++p; 6548334SJose.Borrego@Sun.COM 6558334SJose.Borrego@Sun.COM if (strchr(arg, '+') != NULL) 6568334SJose.Borrego@Sun.COM return; 6578334SJose.Borrego@Sun.COM 6588334SJose.Borrego@Sun.COM *domain = p; 6598334SJose.Borrego@Sun.COM *username = arg; 6608334SJose.Borrego@Sun.COM } else { 6618334SJose.Borrego@Sun.COM *p = '\0'; 6628334SJose.Borrego@Sun.COM ++p; 6638334SJose.Borrego@Sun.COM *username = p; 6648334SJose.Borrego@Sun.COM *domain = arg; 6658334SJose.Borrego@Sun.COM } 6668334SJose.Borrego@Sun.COM } 6678334SJose.Borrego@Sun.COM } 6688334SJose.Borrego@Sun.COM 6698334SJose.Borrego@Sun.COM /* 6705331Samw * smbadm_list 6715331Samw * 6725331Samw * Displays current security mode and domain/workgroup name. 6735331Samw */ 6745331Samw /*ARGSUSED*/ 6755331Samw static int 6765331Samw smbadm_list(int argc, char **argv) 6775331Samw { 6786139Sjb150015 char domain[MAXHOSTNAMELEN]; 6798334SJose.Borrego@Sun.COM char fqdn[MAXHOSTNAMELEN]; 6808334SJose.Borrego@Sun.COM char srvname[MAXHOSTNAMELEN]; 6816139Sjb150015 char modename[16]; 6826139Sjb150015 int rc; 6838670SJose.Borrego@Sun.COM smb_inaddr_t srvipaddr; 6847348SJose.Borrego@Sun.COM char ipstr[INET6_ADDRSTRLEN]; 6855331Samw 6866139Sjb150015 rc = smb_config_getstr(SMB_CI_SECURITY, modename, sizeof (modename)); 6876139Sjb150015 if (rc != SMBD_SMF_OK) { 6885331Samw (void) fprintf(stderr, 6898474SJose.Borrego@Sun.COM gettext("cannot determine the operational mode\n")); 6905331Samw return (1); 6915331Samw } 6925331Samw 6936139Sjb150015 if (smb_getdomainname(domain, sizeof (domain)) != 0) { 6946139Sjb150015 (void) fprintf(stderr, gettext("failed to get the %s name\n"), 6956139Sjb150015 modename); 6965331Samw return (1); 6975331Samw } 6988474SJose.Borrego@Sun.COM 6997348SJose.Borrego@Sun.COM if (strcmp(modename, "workgroup") == 0) { 7008474SJose.Borrego@Sun.COM (void) printf(gettext("[*] [%s]\n"), domain); 7017348SJose.Borrego@Sun.COM return (0); 7027348SJose.Borrego@Sun.COM } 7038474SJose.Borrego@Sun.COM 7048474SJose.Borrego@Sun.COM (void) printf(gettext("[*] [%s]\n"), domain); 7058334SJose.Borrego@Sun.COM if ((smb_getfqdomainname(fqdn, sizeof (fqdn)) == 0) && (*fqdn != '\0')) 7068474SJose.Borrego@Sun.COM (void) printf(gettext("[*] [%s]\n"), fqdn); 7075331Samw 7088334SJose.Borrego@Sun.COM if ((smb_get_dcinfo(srvname, MAXHOSTNAMELEN, &srvipaddr) 7098334SJose.Borrego@Sun.COM == NT_STATUS_SUCCESS) && (*srvname != '\0') && 7108670SJose.Borrego@Sun.COM (!smb_inet_iszero(&srvipaddr))) { 7118670SJose.Borrego@Sun.COM (void) smb_inet_ntop(&srvipaddr, ipstr, 7128670SJose.Borrego@Sun.COM SMB_IPSTRLEN(srvipaddr.a_family)); 7138474SJose.Borrego@Sun.COM (void) printf(gettext("\t[+%s.%s] [%s]\n"), 7148474SJose.Borrego@Sun.COM srvname, fqdn, ipstr); 7157348SJose.Borrego@Sun.COM } 7168474SJose.Borrego@Sun.COM 71710717Samw@Sun.COM smb_domain_show(); 7185331Samw return (0); 7195331Samw } 7205331Samw 7215331Samw /* 7225331Samw * smbadm_group_create 7235331Samw * 7245331Samw * Creates a local SMB group 7255331Samw */ 7265331Samw static int 7275331Samw smbadm_group_create(int argc, char **argv) 7285331Samw { 7295331Samw char *gname = NULL; 7305331Samw char *desc = NULL; 7315331Samw char option; 7325772Sas200622 int status; 7335331Samw 7345331Samw while ((option = getopt(argc, argv, "d:")) != -1) { 7355331Samw switch (option) { 7365331Samw case 'd': 7375331Samw desc = optarg; 7385331Samw break; 7395331Samw 7405331Samw default: 7415331Samw smbadm_usage(B_FALSE); 7425331Samw } 7435331Samw } 7445331Samw 7455331Samw gname = argv[optind]; 7465331Samw if (optind >= argc || gname == NULL || *gname == '\0') { 7475331Samw (void) fprintf(stderr, gettext("missing group name\n")); 7485331Samw smbadm_usage(B_FALSE); 7495331Samw } 7505331Samw 7515331Samw if (getgrnam(gname) == NULL) { 7525331Samw (void) fprintf(stderr, 7535772Sas200622 gettext("failed to get the Solaris group '%s'\n"), gname); 7545331Samw (void) fprintf(stderr, 7555772Sas200622 gettext("use 'groupadd' to add '%s'\n"), gname); 7565331Samw return (1); 7575331Samw } 7585331Samw 7595772Sas200622 status = smb_lgrp_add(gname, desc); 7605772Sas200622 if (status != SMB_LGRP_SUCCESS) { 7615331Samw (void) fprintf(stderr, 762*11633SJoyce.McIntosh@Sun.COM gettext("failed to create %s (%s)\n"), gname, 7635772Sas200622 smb_lgrp_strerror(status)); 7645331Samw } else { 765*11633SJoyce.McIntosh@Sun.COM (void) printf(gettext("%s created\n"), gname); 7665331Samw } 7675331Samw 7685331Samw return (status); 7695331Samw } 7705331Samw 7715331Samw /* 7725331Samw * smbadm_group_dump_members 7735331Samw * 7745331Samw * Dump group members details. 7755331Samw */ 7765331Samw static void 7775772Sas200622 smbadm_group_dump_members(smb_gsid_t *members, int num) 7785331Samw { 77911337SWilliam.Krier@Sun.COM char sidstr[SMB_SID_STRSZ]; 78011337SWilliam.Krier@Sun.COM lsa_account_t acct; 78111337SWilliam.Krier@Sun.COM int i; 7825331Samw 7835772Sas200622 if (num == 0) { 7845331Samw (void) printf(gettext("\tNo members\n")); 7855331Samw return; 7865331Samw } 7875331Samw 7885331Samw (void) printf(gettext("\tMembers:\n")); 7895772Sas200622 for (i = 0; i < num; i++) { 79011337SWilliam.Krier@Sun.COM smb_sid_tostr(members[i].gs_sid, sidstr); 79111337SWilliam.Krier@Sun.COM 79211337SWilliam.Krier@Sun.COM if (smb_lookup_sid(sidstr, &acct) == 0) { 79311337SWilliam.Krier@Sun.COM if (acct.a_status == NT_STATUS_SUCCESS) 79411337SWilliam.Krier@Sun.COM smbadm_group_show_name(acct.a_domain, 79511337SWilliam.Krier@Sun.COM acct.a_name); 79611337SWilliam.Krier@Sun.COM else 79711337SWilliam.Krier@Sun.COM (void) printf(gettext("\t\t%s [%s]\n"), 79811337SWilliam.Krier@Sun.COM sidstr, xlate_nt_status(acct.a_status)); 79911337SWilliam.Krier@Sun.COM } else { 8006600Sas200622 (void) printf(gettext("\t\t%s\n"), sidstr); 80111337SWilliam.Krier@Sun.COM } 8025331Samw } 8035331Samw } 8045331Samw 80511337SWilliam.Krier@Sun.COM static void 80611337SWilliam.Krier@Sun.COM smbadm_group_show_name(const char *domain, const char *name) 80711337SWilliam.Krier@Sun.COM { 80811337SWilliam.Krier@Sun.COM if (strchr(domain, '.') != NULL) 80911337SWilliam.Krier@Sun.COM (void) printf(gettext("\t\t%s@%s\n"), name, domain); 81011337SWilliam.Krier@Sun.COM else 81111337SWilliam.Krier@Sun.COM (void) printf(gettext("\t\t%s\\%s\n"), domain, name); 81211337SWilliam.Krier@Sun.COM } 81311337SWilliam.Krier@Sun.COM 8145331Samw /* 8155331Samw * smbadm_group_dump_privs 8165331Samw * 8175331Samw * Dump group privilege details. 8185331Samw */ 8195331Samw static void 8205772Sas200622 smbadm_group_dump_privs(smb_privset_t *privs) 8215331Samw { 8225772Sas200622 smb_privinfo_t *pinfo; 8235772Sas200622 char *pstatus; 8245331Samw int i; 8255331Samw 8265331Samw (void) printf(gettext("\tPrivileges: \n")); 8275331Samw 8285772Sas200622 for (i = 0; i < privs->priv_cnt; i++) { 8295772Sas200622 pinfo = smb_priv_getbyvalue(privs->priv[i].luid.lo_part); 8305772Sas200622 if ((pinfo == NULL) || (pinfo->flags & PF_PRESENTABLE) == 0) 8315331Samw continue; 8325331Samw 8335772Sas200622 switch (privs->priv[i].attrs) { 8345772Sas200622 case SE_PRIVILEGE_ENABLED: 8355772Sas200622 pstatus = "On"; 8365772Sas200622 break; 8375772Sas200622 case SE_PRIVILEGE_DISABLED: 8385772Sas200622 pstatus = "Off"; 8395772Sas200622 break; 8405772Sas200622 default: 8415772Sas200622 pstatus = "Unknown"; 8425772Sas200622 break; 8435331Samw } 8445772Sas200622 (void) printf(gettext("\t\t%s: %s\n"), pinfo->name, pstatus); 8455331Samw } 8465331Samw 8475772Sas200622 if (privs->priv_cnt == 0) 8485331Samw (void) printf(gettext("\t\tNo privileges\n")); 8495331Samw } 8505331Samw 8515331Samw /* 8525331Samw * smbadm_group_dump 8535331Samw * 8545331Samw * Dump group details. 8555331Samw */ 8565772Sas200622 static void 8575772Sas200622 smbadm_group_dump(smb_group_t *grp, boolean_t show_mem, boolean_t show_privs) 8585331Samw { 8596432Sas200622 char sidstr[SMB_SID_STRSZ]; 8605331Samw 8615772Sas200622 (void) printf(gettext("%s (%s)\n"), grp->sg_name, grp->sg_cmnt); 8625331Samw 8636432Sas200622 smb_sid_tostr(grp->sg_id.gs_sid, sidstr); 8645772Sas200622 (void) printf(gettext("\tSID: %s\n"), sidstr); 8655331Samw 8665772Sas200622 if (show_privs) 8675772Sas200622 smbadm_group_dump_privs(grp->sg_privs); 8685331Samw 8695772Sas200622 if (show_mem) 8705772Sas200622 smbadm_group_dump_members(grp->sg_members, grp->sg_nmembers); 8715331Samw } 8725331Samw 8735331Samw /* 8745331Samw * smbadm_group_show 8755331Samw * 8765331Samw */ 8775331Samw static int 8785331Samw smbadm_group_show(int argc, char **argv) 8795331Samw { 8805331Samw char *gname = NULL; 8815331Samw boolean_t show_privs; 8825331Samw boolean_t show_members; 8835331Samw char option; 8845772Sas200622 int status; 8855772Sas200622 smb_group_t grp; 8865772Sas200622 smb_giter_t gi; 8875331Samw 8885331Samw show_privs = show_members = B_FALSE; 8895331Samw 8905331Samw while ((option = getopt(argc, argv, "mp")) != -1) { 8915331Samw switch (option) { 8925331Samw case 'm': 8935331Samw show_members = B_TRUE; 8945331Samw break; 8955331Samw case 'p': 8965331Samw show_privs = B_TRUE; 8975331Samw break; 8985331Samw 8995331Samw default: 9005331Samw smbadm_usage(B_FALSE); 9015331Samw } 9025331Samw } 9035331Samw 9045331Samw gname = argv[optind]; 9055331Samw if (optind >= argc || gname == NULL || *gname == '\0') 9065331Samw gname = "*"; 9075331Samw 9085772Sas200622 if (strcmp(gname, "*")) { 9095772Sas200622 status = smb_lgrp_getbyname(gname, &grp); 9105772Sas200622 if (status == SMB_LGRP_SUCCESS) { 9115772Sas200622 smbadm_group_dump(&grp, show_members, show_privs); 9125772Sas200622 smb_lgrp_free(&grp); 9135772Sas200622 } else { 9145772Sas200622 (void) fprintf(stderr, 9158334SJose.Borrego@Sun.COM gettext("failed to find %s (%s)\n"), 9165772Sas200622 gname, smb_lgrp_strerror(status)); 9175772Sas200622 } 9185772Sas200622 return (status); 9195331Samw } 9205331Samw 9216432Sas200622 if ((status = smb_lgrp_iteropen(&gi)) != SMB_LGRP_SUCCESS) { 9228334SJose.Borrego@Sun.COM (void) fprintf(stderr, gettext("failed to list groups (%s)\n"), 9235772Sas200622 smb_lgrp_strerror(status)); 9245772Sas200622 return (status); 9255331Samw } 9265331Samw 9276432Sas200622 while ((status = smb_lgrp_iterate(&gi, &grp)) == SMB_LGRP_SUCCESS) { 9285772Sas200622 smbadm_group_dump(&grp, show_members, show_privs); 9295772Sas200622 smb_lgrp_free(&grp); 9305772Sas200622 } 9316432Sas200622 9325772Sas200622 smb_lgrp_iterclose(&gi); 9335772Sas200622 9346432Sas200622 if (status != SMB_LGRP_NO_MORE) { 9356432Sas200622 (void) fprintf(stderr, 9366432Sas200622 gettext("failed to get all the groups (%s)\n"), 9376432Sas200622 smb_lgrp_strerror(status)); 9386432Sas200622 return (status); 9396432Sas200622 } 9406432Sas200622 9415772Sas200622 return (0); 9425331Samw } 9435331Samw 9445331Samw /* 9455331Samw * smbadm_group_delete 9465331Samw */ 9475331Samw static int 9485331Samw smbadm_group_delete(int argc, char **argv) 9495331Samw { 9505331Samw char *gname = NULL; 9515772Sas200622 int status; 9525331Samw 9535331Samw gname = argv[optind]; 9545331Samw if (optind >= argc || gname == NULL || *gname == '\0') { 9555331Samw (void) fprintf(stderr, gettext("missing group name\n")); 9565331Samw smbadm_usage(B_FALSE); 9575331Samw } 9585331Samw 9595772Sas200622 status = smb_lgrp_delete(gname); 9605772Sas200622 if (status != SMB_LGRP_SUCCESS) { 9615331Samw (void) fprintf(stderr, 9628334SJose.Borrego@Sun.COM gettext("failed to delete %s (%s)\n"), gname, 9635772Sas200622 smb_lgrp_strerror(status)); 9645331Samw } else { 965*11633SJoyce.McIntosh@Sun.COM (void) printf(gettext("%s deleted\n"), gname); 9665331Samw } 9675331Samw 9685331Samw return (status); 9695331Samw } 9705331Samw 9715331Samw /* 9725331Samw * smbadm_group_rename 9735331Samw */ 9745331Samw static int 9755331Samw smbadm_group_rename(int argc, char **argv) 9765331Samw { 9775331Samw char *gname = NULL; 9785331Samw char *ngname = NULL; 9795772Sas200622 int status; 9805331Samw 9815331Samw gname = argv[optind]; 9825331Samw if (optind++ >= argc || gname == NULL || *gname == '\0') { 9835331Samw (void) fprintf(stderr, gettext("missing group name\n")); 9845331Samw smbadm_usage(B_FALSE); 9855331Samw } 9865331Samw 9875331Samw ngname = argv[optind]; 9885331Samw if (optind >= argc || ngname == NULL || *ngname == '\0') { 9895331Samw (void) fprintf(stderr, gettext("missing new group name\n")); 9905331Samw smbadm_usage(B_FALSE); 9915331Samw } 9925331Samw 9935772Sas200622 if (getgrnam(ngname) == NULL) { 9945331Samw (void) fprintf(stderr, 9955772Sas200622 gettext("failed to get the Solaris group '%s'\n"), ngname); 9965331Samw (void) fprintf(stderr, 9975772Sas200622 gettext("use 'groupadd' to add '%s'\n"), ngname); 9985331Samw return (1); 9995331Samw } 10005331Samw 10015772Sas200622 status = smb_lgrp_rename(gname, ngname); 10025772Sas200622 if (status != SMB_LGRP_SUCCESS) { 10035772Sas200622 if (status == SMB_LGRP_EXISTS) 10045772Sas200622 (void) fprintf(stderr, 10055772Sas200622 gettext("failed to rename '%s' (%s already " 10065772Sas200622 "exists)\n"), gname, ngname); 10075772Sas200622 else 10085772Sas200622 (void) fprintf(stderr, 10095772Sas200622 gettext("failed to rename '%s' (%s)\n"), gname, 10105772Sas200622 smb_lgrp_strerror(status)); 10115331Samw } else { 10125772Sas200622 (void) printf(gettext("'%s' renamed to '%s'\n"), gname, ngname); 10135331Samw } 10145331Samw 10155331Samw return (status); 10165331Samw } 10175331Samw 10185331Samw /* 10195331Samw * smbadm_group_setprop 10205331Samw * 10215331Samw * Set the group properties. 10225331Samw */ 10235331Samw static int 10245331Samw smbadm_group_setprop(int argc, char **argv) 10255331Samw { 10265331Samw char *gname = NULL; 10275331Samw smbadm_prop_t props[SMBADM_NPROP]; 10285331Samw smbadm_prop_handle_t *phandle; 10295331Samw char option; 10305331Samw int pcnt = 0; 10315331Samw int ret; 10325331Samw int p; 10335331Samw 10345331Samw bzero(props, SMBADM_NPROP * sizeof (smbadm_prop_t)); 10355331Samw 10365331Samw while ((option = getopt(argc, argv, "p:")) != -1) { 10375331Samw switch (option) { 10385331Samw case 'p': 10395331Samw if (pcnt >= SMBADM_NPROP) { 10405331Samw (void) fprintf(stderr, 10415331Samw gettext("exceeded number of supported" 10425331Samw " properties\n")); 10435331Samw smbadm_usage(B_FALSE); 10445331Samw } 10455331Samw 10465772Sas200622 if (smbadm_prop_parse(optarg, &props[pcnt++]) != 0) 10475772Sas200622 smbadm_usage(B_FALSE); 10485331Samw break; 10495331Samw 10505331Samw default: 10515331Samw smbadm_usage(B_FALSE); 10525331Samw } 10535331Samw } 10545331Samw 10555331Samw if (pcnt == 0) { 10565331Samw (void) fprintf(stderr, 10575331Samw gettext("missing property=value argument\n")); 10585331Samw smbadm_usage(B_FALSE); 10595331Samw } 10605331Samw 10615331Samw gname = argv[optind]; 10625331Samw if (optind >= argc || gname == NULL || *gname == '\0') { 10635331Samw (void) fprintf(stderr, gettext("missing group name\n")); 10645331Samw smbadm_usage(B_FALSE); 10655331Samw } 10665331Samw 10675331Samw for (p = 0; p < pcnt; p++) { 10685331Samw phandle = smbadm_prop_gethandle(props[p].p_name); 10695331Samw if (phandle) { 10705331Samw if (phandle->p_setfn(gname, &props[p]) != 0) 10715331Samw ret = 1; 10725331Samw } 10735331Samw } 10745331Samw 10755331Samw return (ret); 10765331Samw } 10775331Samw 10785331Samw /* 10795331Samw * smbadm_group_getprop 10805331Samw * 10815331Samw * Get the group properties. 10825331Samw */ 10835331Samw static int 10845331Samw smbadm_group_getprop(int argc, char **argv) 10855331Samw { 10865331Samw char *gname = NULL; 10875331Samw smbadm_prop_t props[SMBADM_NPROP]; 10885331Samw smbadm_prop_handle_t *phandle; 10895331Samw char option; 10905331Samw int pcnt = 0; 10915331Samw int ret; 10925331Samw int p; 10935331Samw 10945331Samw bzero(props, SMBADM_NPROP * sizeof (smbadm_prop_t)); 10955331Samw 10965331Samw while ((option = getopt(argc, argv, "p:")) != -1) { 10975331Samw switch (option) { 10985331Samw case 'p': 10995331Samw if (pcnt >= SMBADM_NPROP) { 11005331Samw (void) fprintf(stderr, 11015331Samw gettext("exceeded number of supported" 11025331Samw " properties\n")); 11035331Samw smbadm_usage(B_FALSE); 11045331Samw } 11055331Samw 11065772Sas200622 if (smbadm_prop_parse(optarg, &props[pcnt++]) != 0) 11075772Sas200622 smbadm_usage(B_FALSE); 11085331Samw break; 11095331Samw 11105331Samw default: 11115331Samw smbadm_usage(B_FALSE); 11125331Samw } 11135331Samw } 11145331Samw 11155331Samw gname = argv[optind]; 11165331Samw if (optind >= argc || gname == NULL || *gname == '\0') { 11175331Samw (void) fprintf(stderr, gettext("missing group name\n")); 11185331Samw smbadm_usage(B_FALSE); 11195331Samw } 11205331Samw 11215331Samw if (pcnt == 0) { 11225331Samw /* 11235331Samw * If no property has be specified then get 11245331Samw * all the properties. 11255331Samw */ 11265331Samw pcnt = SMBADM_NPROP; 11275331Samw for (p = 0; p < pcnt; p++) 11285331Samw props[p].p_name = smbadm_ptable[p].p_name; 11295331Samw } 11305331Samw 11315331Samw for (p = 0; p < pcnt; p++) { 11325331Samw phandle = smbadm_prop_gethandle(props[p].p_name); 11335331Samw if (phandle) { 11345331Samw if (phandle->p_getfn(gname, &props[p]) != 0) 11355331Samw ret = 1; 11365331Samw } 11375331Samw } 11385331Samw 11395331Samw return (ret); 11405331Samw } 11415331Samw 11425331Samw /* 11435331Samw * smbadm_group_addmember 11445331Samw * 11455331Samw */ 11465331Samw static int 11475331Samw smbadm_group_addmember(int argc, char **argv) 11485331Samw { 114911337SWilliam.Krier@Sun.COM lsa_account_t acct; 11505331Samw char *gname = NULL; 11515331Samw char **mname; 11525331Samw char option; 11535772Sas200622 smb_gsid_t msid; 11545772Sas200622 int status; 11555331Samw int mcnt = 0; 11565331Samw int ret = 0; 11575331Samw int i; 11585331Samw 11595331Samw 11605331Samw mname = (char **)malloc(argc * sizeof (char *)); 11615331Samw if (mname == NULL) { 11628334SJose.Borrego@Sun.COM warn(gettext("failed to add group member")); 11635331Samw return (1); 11645331Samw } 11655331Samw bzero(mname, argc * sizeof (char *)); 11665331Samw 11675331Samw while ((option = getopt(argc, argv, "m:")) != -1) { 11685331Samw switch (option) { 11695331Samw case 'm': 11705331Samw mname[mcnt++] = optarg; 11715331Samw break; 11725331Samw 11735331Samw default: 11745331Samw free(mname); 11755331Samw smbadm_usage(B_FALSE); 11765331Samw } 11775331Samw } 11785331Samw 11795331Samw if (mcnt == 0) { 11805331Samw (void) fprintf(stderr, gettext("missing member name\n")); 11815331Samw free(mname); 11825331Samw smbadm_usage(B_FALSE); 11835331Samw } 11845331Samw 11855331Samw gname = argv[optind]; 11865331Samw if (optind >= argc || gname == NULL || *gname == 0) { 11875331Samw (void) fprintf(stderr, gettext("missing group name\n")); 11885331Samw free(mname); 11895331Samw smbadm_usage(B_FALSE); 11905331Samw } 11915331Samw 11925331Samw 11935331Samw for (i = 0; i < mcnt; i++) { 119411337SWilliam.Krier@Sun.COM ret = 0; 11955331Samw if (mname[i] == NULL) 11965331Samw continue; 11975331Samw 119811337SWilliam.Krier@Sun.COM ret = smb_lookup_name(mname[i], SidTypeUnknown, &acct); 119911337SWilliam.Krier@Sun.COM if ((ret != 0) || (acct.a_status != NT_STATUS_SUCCESS)) { 12005772Sas200622 (void) fprintf(stderr, 12018334SJose.Borrego@Sun.COM gettext("failed to add %s: unable to obtain SID\n"), 12025772Sas200622 mname[i]); 12035772Sas200622 continue; 12045772Sas200622 } 12055772Sas200622 120611337SWilliam.Krier@Sun.COM msid.gs_type = acct.a_sidtype; 120711337SWilliam.Krier@Sun.COM 120811337SWilliam.Krier@Sun.COM if ((msid.gs_sid = smb_sid_fromstr(acct.a_sid)) == NULL) { 120911337SWilliam.Krier@Sun.COM (void) fprintf(stderr, 121011337SWilliam.Krier@Sun.COM gettext("failed to add %s: no memory\n"), mname[i]); 121111337SWilliam.Krier@Sun.COM continue; 121211337SWilliam.Krier@Sun.COM } 121311337SWilliam.Krier@Sun.COM 12145772Sas200622 status = smb_lgrp_add_member(gname, msid.gs_sid, msid.gs_type); 121511337SWilliam.Krier@Sun.COM smb_sid_free(msid.gs_sid); 12165772Sas200622 if (status != SMB_LGRP_SUCCESS) { 12175331Samw (void) fprintf(stderr, 12185331Samw gettext("failed to add %s (%s)\n"), 12195772Sas200622 mname[i], smb_lgrp_strerror(status)); 12205331Samw ret = 1; 12215772Sas200622 } else { 12225772Sas200622 (void) printf(gettext("'%s' is now a member of '%s'\n"), 12235772Sas200622 mname[i], gname); 12245331Samw } 12255331Samw } 12265331Samw 12275331Samw free(mname); 12285331Samw return (ret); 12295331Samw } 12305331Samw 12315331Samw /* 12325331Samw * smbadm_group_delmember 12335331Samw */ 12345331Samw static int 12355331Samw smbadm_group_delmember(int argc, char **argv) 12365331Samw { 123711337SWilliam.Krier@Sun.COM lsa_account_t acct; 12385331Samw char *gname = NULL; 12395331Samw char **mname; 12405331Samw char option; 12415772Sas200622 smb_gsid_t msid; 12425772Sas200622 int status; 12435331Samw int mcnt = 0; 12445331Samw int ret = 0; 12455331Samw int i; 12465331Samw 12475331Samw mname = (char **)malloc(argc * sizeof (char *)); 12485331Samw if (mname == NULL) { 12498334SJose.Borrego@Sun.COM warn(gettext("failed to delete group member")); 12505331Samw return (1); 12515331Samw } 12525331Samw bzero(mname, argc * sizeof (char *)); 12535331Samw 12545331Samw while ((option = getopt(argc, argv, "m:")) != -1) { 12555331Samw switch (option) { 12565331Samw case 'm': 12575331Samw mname[mcnt++] = optarg; 12585331Samw break; 12595331Samw 12605331Samw default: 12615331Samw free(mname); 12625331Samw smbadm_usage(B_FALSE); 12635331Samw } 12645331Samw } 12655331Samw 12665331Samw if (mcnt == 0) { 12675331Samw (void) fprintf(stderr, gettext("missing member name\n")); 12685331Samw free(mname); 12695331Samw smbadm_usage(B_FALSE); 12705331Samw } 12715331Samw 12725331Samw gname = argv[optind]; 12735331Samw if (optind >= argc || gname == NULL || *gname == 0) { 12745331Samw (void) fprintf(stderr, gettext("missing group name\n")); 12755331Samw free(mname); 12765331Samw smbadm_usage(B_FALSE); 12775331Samw } 12785331Samw 12795331Samw 12805331Samw for (i = 0; i < mcnt; i++) { 128111337SWilliam.Krier@Sun.COM ret = 0; 12825331Samw if (mname[i] == NULL) 12835331Samw continue; 12845331Samw 128511337SWilliam.Krier@Sun.COM ret = smb_lookup_name(mname[i], SidTypeUnknown, &acct); 128611337SWilliam.Krier@Sun.COM if ((ret != 0) || (acct.a_status != NT_STATUS_SUCCESS)) { 12875772Sas200622 (void) fprintf(stderr, 12888334SJose.Borrego@Sun.COM gettext("failed to remove %s: " 12898334SJose.Borrego@Sun.COM "unable to obtain SID\n"), 12905772Sas200622 mname[i]); 12915772Sas200622 continue; 12925772Sas200622 } 12935772Sas200622 129411337SWilliam.Krier@Sun.COM msid.gs_type = acct.a_sidtype; 129511337SWilliam.Krier@Sun.COM 129611337SWilliam.Krier@Sun.COM if ((msid.gs_sid = smb_sid_fromstr(acct.a_sid)) == NULL) { 129711337SWilliam.Krier@Sun.COM (void) fprintf(stderr, 129811337SWilliam.Krier@Sun.COM gettext("failed to remove %s: no memory\n"), 129911337SWilliam.Krier@Sun.COM mname[i]); 130011337SWilliam.Krier@Sun.COM continue; 130111337SWilliam.Krier@Sun.COM } 130211337SWilliam.Krier@Sun.COM 13035772Sas200622 status = smb_lgrp_del_member(gname, msid.gs_sid, msid.gs_type); 130411337SWilliam.Krier@Sun.COM smb_sid_free(msid.gs_sid); 13055772Sas200622 if (status != SMB_LGRP_SUCCESS) { 13065331Samw (void) fprintf(stderr, 13075331Samw gettext("failed to remove %s (%s)\n"), 13085772Sas200622 mname[i], smb_lgrp_strerror(status)); 13095331Samw ret = 1; 13105331Samw } else { 13115331Samw (void) printf( 13125772Sas200622 gettext("'%s' has been removed from %s\n"), 13135331Samw mname[i], gname); 13145331Samw } 13155331Samw } 13165331Samw 13175331Samw return (ret); 13185331Samw } 13195331Samw 13205331Samw static int 13215331Samw smbadm_user_disable(int argc, char **argv) 13225331Samw { 13235331Samw int error; 13245331Samw char *user = NULL; 13255331Samw 13265331Samw user = argv[optind]; 13275331Samw if (optind >= argc || user == NULL || *user == '\0') { 13285331Samw (void) fprintf(stderr, gettext("missing user name\n")); 13295331Samw smbadm_usage(B_FALSE); 13305331Samw } 13315331Samw 13325331Samw error = smb_pwd_setcntl(user, SMB_PWC_DISABLE); 13335331Samw if (error == SMB_PWE_SUCCESS) 13345331Samw (void) printf(gettext("%s is disabled.\n"), user); 13355331Samw else 13365331Samw (void) fprintf(stderr, "%s\n", smbadm_pwd_strerror(error)); 13375331Samw 13385331Samw return (error); 13395331Samw } 13405331Samw 13415331Samw static int 13425331Samw smbadm_user_enable(int argc, char **argv) 13435331Samw { 13445331Samw int error; 13455331Samw char *user = NULL; 13465331Samw 13475331Samw user = argv[optind]; 13485331Samw if (optind >= argc || user == NULL || *user == '\0') { 13495331Samw (void) fprintf(stderr, gettext("missing user name\n")); 13505331Samw smbadm_usage(B_FALSE); 13515331Samw } 13525331Samw 13535331Samw error = smb_pwd_setcntl(user, SMB_PWC_ENABLE); 13545331Samw if (error == SMB_PWE_SUCCESS) 13555331Samw (void) printf(gettext("%s is enabled.\n"), user); 13565331Samw else 13575331Samw (void) fprintf(stderr, "%s\n", smbadm_pwd_strerror(error)); 13585331Samw 13595331Samw return (error); 13605331Samw } 13615331Samw 13625331Samw 13635331Samw int 13645331Samw main(int argc, char **argv) 13655331Samw { 13665772Sas200622 int ret; 13675331Samw int i; 13685331Samw 1369*11633SJoyce.McIntosh@Sun.COM (void) setlocale(LC_ALL, ""); 1370*11633SJoyce.McIntosh@Sun.COM (void) textdomain(TEXT_DOMAIN); 1371*11633SJoyce.McIntosh@Sun.COM 13725331Samw (void) malloc(0); /* satisfy libumem dependency */ 13735331Samw 13745331Samw progname = basename(argv[0]); 13755331Samw 13765331Samw if (getzoneid() != GLOBAL_ZONEID) { 13775331Samw (void) fprintf(stderr, 13785331Samw gettext("cannot execute in non-global zone\n")); 13795331Samw return (0); 13805331Samw } 13815331Samw 13825331Samw if (is_system_labeled()) { 13835331Samw (void) fprintf(stderr, 13845331Samw gettext("Trusted Extensions not supported\n")); 13855331Samw return (0); 13865331Samw } 13875331Samw 13885331Samw if (argc < 2) { 13895331Samw (void) fprintf(stderr, gettext("missing command\n")); 13905331Samw smbadm_usage(B_FALSE); 13915331Samw } 13925331Samw 13935331Samw /* 13945331Samw * Special case "cmd --help/-?" 13955331Samw */ 13965331Samw if (strcmp(argv[1], "-?") == 0 || 13975331Samw strcmp(argv[1], "--help") == 0 || 13985331Samw strcmp(argv[1], "-h") == 0) 13995331Samw smbadm_usage(B_TRUE); 14005331Samw 14015331Samw for (i = 0; i < SMBADM_NCMD; ++i) { 14025331Samw curcmd = &smbadm_cmdtable[i]; 14035331Samw if (strcasecmp(argv[1], curcmd->name) == 0) { 14045331Samw if (argc > 2) { 14055331Samw /* cmd subcmd --help/-? */ 14065331Samw if (strcmp(argv[2], "-?") == 0 || 14075331Samw strcmp(argv[2], "--help") == 0 || 14085331Samw strcmp(argv[2], "-h") == 0) 14095331Samw smbadm_usage(B_TRUE); 14105331Samw } 14115331Samw 1412*11633SJoyce.McIntosh@Sun.COM if (!smbadm_checkauth(curcmd->auth)) { 1413*11633SJoyce.McIntosh@Sun.COM (void) fprintf(stderr, 1414*11633SJoyce.McIntosh@Sun.COM gettext("%s: %s: authorization denied\n"), 1415*11633SJoyce.McIntosh@Sun.COM progname, curcmd->name); 1416*11633SJoyce.McIntosh@Sun.COM return (1); 1417*11633SJoyce.McIntosh@Sun.COM } 1418*11633SJoyce.McIntosh@Sun.COM 14197052Samw if ((ret = smbadm_init()) != 0) 14206139Sjb150015 return (ret); 14215772Sas200622 14225772Sas200622 ret = curcmd->func(argc - 1, &argv[1]); 14236139Sjb150015 14247052Samw smbadm_fini(); 14255772Sas200622 return (ret); 14265331Samw } 14275331Samw } 14285331Samw 14295331Samw curcmd = NULL; 14305331Samw (void) fprintf(stderr, gettext("unknown subcommand (%s)\n"), argv[1]); 14315331Samw smbadm_usage(B_FALSE); 14325331Samw return (2); 14335331Samw } 14345331Samw 14356139Sjb150015 static int 14367052Samw smbadm_init(void) 14376139Sjb150015 { 14386139Sjb150015 int rc; 14396139Sjb150015 14407052Samw switch (curcmd->flags & SMBADM_CMDF_TYPEMASK) { 14417052Samw case SMBADM_CMDF_GROUP: 14426139Sjb150015 if (smb_idmap_start() != 0) { 14436139Sjb150015 (void) fprintf(stderr, 14446139Sjb150015 gettext("failed to contact idmap service\n")); 14456139Sjb150015 return (1); 14466139Sjb150015 } 14476139Sjb150015 14486139Sjb150015 if ((rc = smb_lgrp_start()) != SMB_LGRP_SUCCESS) { 14496139Sjb150015 (void) fprintf(stderr, 14506139Sjb150015 gettext("failed to initialize (%s)\n"), 14516139Sjb150015 smb_lgrp_strerror(rc)); 14526139Sjb150015 smb_idmap_stop(); 14536139Sjb150015 return (1); 14546139Sjb150015 } 14557052Samw break; 14567052Samw 14577052Samw case SMBADM_CMDF_USER: 14587052Samw smb_pwd_init(B_FALSE); 14597052Samw break; 14607052Samw 14617052Samw default: 14627052Samw break; 14636139Sjb150015 } 14646139Sjb150015 14656139Sjb150015 return (0); 14666139Sjb150015 } 14676139Sjb150015 14686139Sjb150015 static void 14697052Samw smbadm_fini(void) 14706139Sjb150015 { 14717052Samw switch (curcmd->flags & SMBADM_CMDF_TYPEMASK) { 14727052Samw case SMBADM_CMDF_GROUP: 14736139Sjb150015 smb_lgrp_stop(); 14746139Sjb150015 smb_idmap_stop(); 14757052Samw break; 14767052Samw 14777052Samw case SMBADM_CMDF_USER: 14787052Samw smb_pwd_fini(); 14797052Samw break; 14807052Samw 14817052Samw default: 14827052Samw break; 14836139Sjb150015 } 14846139Sjb150015 } 14856139Sjb150015 14865331Samw static boolean_t 1487*11633SJoyce.McIntosh@Sun.COM smbadm_checkauth(const char *auth) 1488*11633SJoyce.McIntosh@Sun.COM { 1489*11633SJoyce.McIntosh@Sun.COM struct passwd *pw; 1490*11633SJoyce.McIntosh@Sun.COM 1491*11633SJoyce.McIntosh@Sun.COM if ((pw = getpwuid(getuid())) == NULL) 1492*11633SJoyce.McIntosh@Sun.COM return (B_FALSE); 1493*11633SJoyce.McIntosh@Sun.COM 1494*11633SJoyce.McIntosh@Sun.COM if (chkauthattr(auth, pw->pw_name) == 0) 1495*11633SJoyce.McIntosh@Sun.COM return (B_FALSE); 1496*11633SJoyce.McIntosh@Sun.COM 1497*11633SJoyce.McIntosh@Sun.COM return (B_TRUE); 1498*11633SJoyce.McIntosh@Sun.COM } 1499*11633SJoyce.McIntosh@Sun.COM 1500*11633SJoyce.McIntosh@Sun.COM static boolean_t 15015331Samw smbadm_prop_validate(smbadm_prop_t *prop, boolean_t chkval) 15025331Samw { 15035331Samw smbadm_prop_handle_t *pinfo; 15045331Samw int i; 15055331Samw 15065331Samw for (i = 0; i < SMBADM_NPROP; i++) { 15075331Samw pinfo = &smbadm_ptable[i]; 15085331Samw if (strcmp(pinfo->p_name, prop->p_name) == 0) { 15095331Samw if (pinfo->p_chkfn && chkval) 15105331Samw return (pinfo->p_chkfn(prop)); 15115331Samw 15125331Samw return (B_TRUE); 15135331Samw } 15145331Samw } 15155331Samw 15168334SJose.Borrego@Sun.COM (void) fprintf(stderr, gettext("unrecognized property '%s'\n"), 15178334SJose.Borrego@Sun.COM prop->p_name); 15185331Samw 15195331Samw return (B_FALSE); 15205331Samw } 15215331Samw 15225331Samw static int 15235331Samw smbadm_prop_parse(char *arg, smbadm_prop_t *prop) 15245331Samw { 15255331Samw boolean_t parse_value; 15265331Samw char *equal; 15275331Samw 15285331Samw if (arg == NULL) 15295331Samw return (2); 15305331Samw 15315331Samw prop->p_name = prop->p_value = NULL; 15325331Samw 15335331Samw if (strcmp(curcmd->name, "set") == 0) 15345331Samw parse_value = B_TRUE; 15355331Samw else 15365331Samw parse_value = B_FALSE; 15375331Samw 15385331Samw prop->p_name = arg; 15395331Samw 15405331Samw if (parse_value) { 15415331Samw equal = strchr(arg, '='); 15425331Samw if (equal == NULL) 15435331Samw return (2); 15445331Samw 15455331Samw *equal++ = '\0'; 15465331Samw prop->p_value = equal; 15475331Samw } 15485331Samw 15495331Samw if (smbadm_prop_validate(prop, parse_value) == B_FALSE) 15505331Samw return (2); 15515331Samw 15525331Samw return (0); 15535331Samw } 15545331Samw 15555331Samw static smbadm_prop_handle_t * 15565331Samw smbadm_prop_gethandle(char *pname) 15575331Samw { 15585331Samw int i; 15595331Samw 15605331Samw for (i = 0; i < SMBADM_NPROP; i++) 15615331Samw if (strcmp(pname, smbadm_ptable[i].p_name) == 0) 15625331Samw return (&smbadm_ptable[i]); 15635331Samw 15645331Samw return (NULL); 15655331Samw } 15665331Samw 15675331Samw static int 15685331Samw smbadm_setprop_desc(char *gname, smbadm_prop_t *prop) 15695331Samw { 15705772Sas200622 int status; 15715331Samw 15725772Sas200622 status = smb_lgrp_setcmnt(gname, prop->p_value); 15735772Sas200622 if (status != SMB_LGRP_SUCCESS) { 15745331Samw (void) fprintf(stderr, 15755331Samw gettext("failed to modify the group description (%s)\n"), 15765772Sas200622 smb_lgrp_strerror(status)); 15775331Samw return (1); 15785331Samw } 15795331Samw 15808334SJose.Borrego@Sun.COM (void) printf(gettext("%s: description modified\n"), gname); 15815331Samw return (0); 15825331Samw } 15835331Samw 15845331Samw static int 15855331Samw smbadm_getprop_desc(char *gname, smbadm_prop_t *prop) 15865331Samw { 15875772Sas200622 char *cmnt = NULL; 15885772Sas200622 int status; 15895331Samw 15905772Sas200622 status = smb_lgrp_getcmnt(gname, &cmnt); 15915772Sas200622 if (status != SMB_LGRP_SUCCESS) { 15925331Samw (void) fprintf(stderr, 15935772Sas200622 gettext("failed to get the group description (%s)\n"), 15945772Sas200622 smb_lgrp_strerror(status)); 15955331Samw return (1); 15965331Samw } 15975331Samw 15985772Sas200622 (void) printf(gettext("\t%s: %s\n"), prop->p_name, cmnt); 15995772Sas200622 free(cmnt); 16005331Samw return (0); 16015331Samw } 16025331Samw 16035331Samw static int 16045772Sas200622 smbadm_group_setpriv(char *gname, uint8_t priv_id, smbadm_prop_t *prop) 16055331Samw { 16065772Sas200622 boolean_t enable; 16075772Sas200622 int status; 16085331Samw int ret; 16095331Samw 16105331Samw if (strcasecmp(prop->p_value, "on") == 0) { 16115331Samw (void) printf(gettext("Enabling %s privilege "), prop->p_name); 16125772Sas200622 enable = B_TRUE; 16135331Samw } else { 16145331Samw (void) printf(gettext("Disabling %s privilege "), prop->p_name); 16155772Sas200622 enable = B_FALSE; 16165331Samw } 16175331Samw 16185772Sas200622 status = smb_lgrp_setpriv(gname, priv_id, enable); 16195772Sas200622 if (status == SMB_LGRP_SUCCESS) { 16205331Samw (void) printf(gettext("succeeded\n")); 16215331Samw ret = 0; 16225331Samw } else { 16235772Sas200622 (void) printf(gettext("failed: %s\n"), 16245772Sas200622 smb_lgrp_strerror(status)); 16255331Samw ret = 1; 16265331Samw } 16275331Samw 16285331Samw return (ret); 16295331Samw } 16305331Samw 16315331Samw static int 16325772Sas200622 smbadm_group_getpriv(char *gname, uint8_t priv_id, smbadm_prop_t *prop) 16335331Samw { 16345772Sas200622 boolean_t enable; 16355772Sas200622 int status; 16365331Samw 16375772Sas200622 status = smb_lgrp_getpriv(gname, priv_id, &enable); 16385772Sas200622 if (status != SMB_LGRP_SUCCESS) { 16395331Samw (void) fprintf(stderr, gettext("failed to get %s (%s)\n"), 16405772Sas200622 prop->p_name, smb_lgrp_strerror(status)); 16415331Samw return (1); 16425331Samw } 16435331Samw 16445772Sas200622 (void) printf(gettext("\t%s: %s\n"), prop->p_name, 16455772Sas200622 (enable) ? "On" : "Off"); 16465331Samw 16475331Samw return (0); 16485331Samw } 16495331Samw 16505331Samw static int 16515331Samw smbadm_setprop_tkowner(char *gname, smbadm_prop_t *prop) 16525331Samw { 16535331Samw return (smbadm_group_setpriv(gname, SE_TAKE_OWNERSHIP_LUID, prop)); 16545331Samw } 16555331Samw 16565331Samw static int 16575331Samw smbadm_getprop_tkowner(char *gname, smbadm_prop_t *prop) 16585331Samw { 16595331Samw return (smbadm_group_getpriv(gname, SE_TAKE_OWNERSHIP_LUID, prop)); 16605331Samw } 16615331Samw 16625331Samw static int 16635331Samw smbadm_setprop_backup(char *gname, smbadm_prop_t *prop) 16645331Samw { 16655331Samw return (smbadm_group_setpriv(gname, SE_BACKUP_LUID, prop)); 16665331Samw } 16675331Samw 16685331Samw static int 16695331Samw smbadm_getprop_backup(char *gname, smbadm_prop_t *prop) 16705331Samw { 16715331Samw return (smbadm_group_getpriv(gname, SE_BACKUP_LUID, prop)); 16725331Samw } 16735331Samw 16745331Samw static int 16755331Samw smbadm_setprop_restore(char *gname, smbadm_prop_t *prop) 16765331Samw { 16775331Samw return (smbadm_group_setpriv(gname, SE_RESTORE_LUID, prop)); 16785331Samw } 16795331Samw 16805331Samw static int 16815331Samw smbadm_getprop_restore(char *gname, smbadm_prop_t *prop) 16825331Samw { 16835331Samw return (smbadm_group_getpriv(gname, SE_RESTORE_LUID, prop)); 16845331Samw } 16855331Samw 16865331Samw static boolean_t 16875331Samw smbadm_chkprop_priv(smbadm_prop_t *prop) 16885331Samw { 16895331Samw if (prop->p_value == NULL || *prop->p_value == '\0') { 16905331Samw (void) fprintf(stderr, 16915331Samw gettext("missing value for '%s'\n"), prop->p_name); 16925331Samw return (B_FALSE); 16935331Samw } 16945331Samw 16955331Samw if (strcasecmp(prop->p_value, "on") == 0) 16965331Samw return (B_TRUE); 16975331Samw 16985331Samw if (strcasecmp(prop->p_value, "off") == 0) 16995331Samw return (B_TRUE); 17005331Samw 17015331Samw (void) fprintf(stderr, 17025331Samw gettext("%s: unrecognized value for '%s' property\n"), 17035331Samw prop->p_value, prop->p_name); 17045331Samw 17055331Samw return (B_FALSE); 17065331Samw } 17075331Samw 17085331Samw static const char * 17095331Samw smbadm_pwd_strerror(int error) 17105331Samw { 17115331Samw switch (error) { 17125331Samw case SMB_PWE_SUCCESS: 17135331Samw return (gettext("Success.")); 17145331Samw 17155331Samw case SMB_PWE_USER_UNKNOWN: 17165331Samw return (gettext("User does not exist.")); 17175331Samw 17185331Samw case SMB_PWE_USER_DISABLE: 17198334SJose.Borrego@Sun.COM return (gettext("User is disabled.")); 17205331Samw 17215331Samw case SMB_PWE_CLOSE_FAILED: 17225331Samw case SMB_PWE_OPEN_FAILED: 17235331Samw case SMB_PWE_WRITE_FAILED: 17245331Samw case SMB_PWE_UPDATE_FAILED: 17255331Samw return (gettext("Unexpected failure. " 17265331Samw "SMB password database unchanged.")); 17275331Samw 17285331Samw case SMB_PWE_STAT_FAILED: 17295331Samw return (gettext("stat of SMB password file failed.")); 17305331Samw 17315331Samw case SMB_PWE_BUSY: 17325331Samw return (gettext("SMB password database busy. " 17335331Samw "Try again later.")); 17345331Samw 17355331Samw case SMB_PWE_DENIED: 17365331Samw return (gettext("Operation not permitted.")); 17375331Samw 17385331Samw case SMB_PWE_SYSTEM_ERROR: 17395331Samw return (gettext("System error.")); 17407052Samw 17417052Samw default: 17427052Samw break; 17435331Samw } 17445331Samw 17455331Samw return (gettext("Unknown error code.")); 17465331Samw } 17475331Samw 17485331Samw /* 17495331Samw * Enable libumem debugging by default on DEBUG builds. 17505331Samw */ 17515331Samw #ifdef DEBUG 17525331Samw const char * 17535331Samw _umem_debug_init(void) 17545331Samw { 17555331Samw return ("default,verbose"); /* $UMEM_DEBUG setting */ 17565331Samw } 17575331Samw 17585331Samw const char * 17595331Samw _umem_logging_init(void) 17605331Samw { 17615331Samw return ("fail,contents"); /* $UMEM_LOGGING setting */ 17625331Samw } 17635331Samw #endif 1764