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 /* 228474SJose.Borrego@Sun.COM * Copyright 2009 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> 345331Samw #include <stdio.h> 355331Samw #include <syslog.h> 365331Samw #include <strings.h> 375331Samw #include <limits.h> 385331Samw #include <getopt.h> 395331Samw #include <libintl.h> 405331Samw #include <zone.h> 415331Samw #include <grp.h> 425331Samw #include <libgen.h> 437348SJose.Borrego@Sun.COM #include <netinet/in.h> 445331Samw #include <smbsrv/libsmb.h> 455331Samw 465331Samw typedef enum { 475331Samw HELP_ADD_MEMBER, 485331Samw HELP_CREATE, 495331Samw HELP_DELETE, 505331Samw HELP_DEL_MEMBER, 515331Samw HELP_GET, 525331Samw HELP_JOIN, 535331Samw HELP_LIST, 545331Samw HELP_RENAME, 555331Samw HELP_SET, 565331Samw HELP_SHOW, 577052Samw HELP_USER_DISABLE, 587052Samw HELP_USER_ENABLE 595331Samw } smbadm_help_t; 605331Samw 617052Samw #define SMBADM_CMDF_USER 0x01 627052Samw #define SMBADM_CMDF_GROUP 0x02 637052Samw #define SMBADM_CMDF_TYPEMASK 0x0F 646139Sjb150015 657348SJose.Borrego@Sun.COM #define SMBADM_ANSBUFSIZ 64 667348SJose.Borrego@Sun.COM 675331Samw typedef struct smbadm_cmdinfo { 685331Samw char *name; 695331Samw int (*func)(int, char **); 705331Samw smbadm_help_t usage; 716139Sjb150015 uint32_t flags; 725331Samw } smbadm_cmdinfo_t; 735331Samw 745331Samw smbadm_cmdinfo_t *curcmd; 755331Samw static char *progname; 765331Samw 778334SJose.Borrego@Sun.COM static void smbadm_usage(boolean_t); 788334SJose.Borrego@Sun.COM static int smbadm_join_workgroup(const char *); 798334SJose.Borrego@Sun.COM static int smbadm_join_domain(const char *, const char *); 808334SJose.Borrego@Sun.COM static void smbadm_extract_domain(char *, char **, char **); 818334SJose.Borrego@Sun.COM 825331Samw static int smbadm_join(int, char **); 835331Samw static int smbadm_list(int, char **); 845331Samw static int smbadm_group_create(int, char **); 855331Samw static int smbadm_group_delete(int, char **); 865331Samw static int smbadm_group_rename(int, char **); 875331Samw static int smbadm_group_show(int, char **); 88*11337SWilliam.Krier@Sun.COM static void smbadm_group_show_name(const char *, const char *); 895331Samw static int smbadm_group_getprop(int, char **); 905331Samw static int smbadm_group_setprop(int, char **); 915331Samw static int smbadm_group_addmember(int, char **); 925331Samw static int smbadm_group_delmember(int, char **); 935331Samw static int smbadm_user_disable(int, char **); 945331Samw static int smbadm_user_enable(int, char **); 955331Samw 965331Samw static smbadm_cmdinfo_t smbadm_cmdtable[] = 975331Samw { 986139Sjb150015 { "add-member", smbadm_group_addmember, HELP_ADD_MEMBER, 996139Sjb150015 SMBADM_CMDF_GROUP }, 1006139Sjb150015 { "create", smbadm_group_create, HELP_CREATE, 1016139Sjb150015 SMBADM_CMDF_GROUP }, 1026139Sjb150015 { "delete", smbadm_group_delete, HELP_DELETE, 1036139Sjb150015 SMBADM_CMDF_GROUP }, 1047052Samw { "disable-user", smbadm_user_disable, HELP_USER_DISABLE, 1057052Samw SMBADM_CMDF_USER }, 1067052Samw { "enable-user", smbadm_user_enable, HELP_USER_ENABLE, 1077052Samw SMBADM_CMDF_USER }, 1086139Sjb150015 { "get", smbadm_group_getprop, HELP_GET, 1096139Sjb150015 SMBADM_CMDF_GROUP }, 1106139Sjb150015 { "join", smbadm_join, HELP_JOIN, 0 }, 1116139Sjb150015 { "list", smbadm_list, HELP_LIST, 0 }, 1126139Sjb150015 { "remove-member", smbadm_group_delmember, HELP_DEL_MEMBER, 1136139Sjb150015 SMBADM_CMDF_GROUP }, 1146139Sjb150015 { "rename", smbadm_group_rename, HELP_RENAME, 1156139Sjb150015 SMBADM_CMDF_GROUP }, 1166139Sjb150015 { "set", smbadm_group_setprop, HELP_SET, 1176139Sjb150015 SMBADM_CMDF_GROUP }, 1186139Sjb150015 { "show", smbadm_group_show, HELP_SHOW, 1196139Sjb150015 SMBADM_CMDF_GROUP }, 1205331Samw }; 1215331Samw 1225331Samw #define SMBADM_NCMD (sizeof (smbadm_cmdtable) / sizeof (smbadm_cmdtable[0])) 1235331Samw 1245331Samw typedef struct smbadm_prop { 1255331Samw char *p_name; 1265331Samw char *p_value; 1275331Samw } smbadm_prop_t; 1285331Samw 1295331Samw typedef struct smbadm_prop_handle { 1305331Samw char *p_name; 1315331Samw char *p_dispvalue; 1325331Samw int (*p_setfn)(char *, smbadm_prop_t *); 1335331Samw int (*p_getfn)(char *, smbadm_prop_t *); 1345331Samw boolean_t (*p_chkfn)(smbadm_prop_t *); 1355331Samw } smbadm_prop_handle_t; 1365331Samw 1375331Samw static boolean_t smbadm_prop_validate(smbadm_prop_t *prop, boolean_t chkval); 1385331Samw static int smbadm_prop_parse(char *arg, smbadm_prop_t *prop); 1395331Samw static smbadm_prop_handle_t *smbadm_prop_gethandle(char *pname); 1405331Samw 1415331Samw static boolean_t smbadm_chkprop_priv(smbadm_prop_t *prop); 1425331Samw static int smbadm_setprop_tkowner(char *gname, smbadm_prop_t *prop); 1435331Samw static int smbadm_getprop_tkowner(char *gname, smbadm_prop_t *prop); 1445331Samw static int smbadm_setprop_backup(char *gname, smbadm_prop_t *prop); 1455331Samw static int smbadm_getprop_backup(char *gname, smbadm_prop_t *prop); 1465331Samw static int smbadm_setprop_restore(char *gname, smbadm_prop_t *prop); 1475331Samw static int smbadm_getprop_restore(char *gname, smbadm_prop_t *prop); 1485331Samw static int smbadm_setprop_desc(char *gname, smbadm_prop_t *prop); 1495331Samw static int smbadm_getprop_desc(char *gname, smbadm_prop_t *prop); 1505331Samw 1515331Samw static smbadm_prop_handle_t smbadm_ptable[] = { 1525331Samw {"backup", "on | off", smbadm_setprop_backup, 1535331Samw smbadm_getprop_backup, smbadm_chkprop_priv }, 1545331Samw {"restore", "on | off", smbadm_setprop_restore, 1555331Samw smbadm_getprop_restore, smbadm_chkprop_priv }, 1565331Samw {"take-ownership", "on | off", smbadm_setprop_tkowner, 1575331Samw smbadm_getprop_tkowner, smbadm_chkprop_priv }, 1585331Samw {"description", "<string>", smbadm_setprop_desc, 1595331Samw smbadm_getprop_desc, NULL }, 1605331Samw }; 1615331Samw 1627052Samw static int smbadm_init(void); 1637052Samw static void smbadm_fini(void); 1645331Samw static const char *smbadm_pwd_strerror(int error); 1655331Samw 1665331Samw /* 1675331Samw * Number of supported properties 1685331Samw */ 1695331Samw #define SMBADM_NPROP (sizeof (smbadm_ptable) / sizeof (smbadm_ptable[0])) 1705331Samw 1715331Samw static void 1725331Samw smbadm_cmdusage(FILE *fp, smbadm_cmdinfo_t *cmd) 1735331Samw { 1745331Samw switch (cmd->usage) { 1755331Samw case HELP_ADD_MEMBER: 1765331Samw (void) fprintf(fp, 1775331Samw gettext("\t%s -m member [[-m member] ...] group\n"), 1785331Samw cmd->name); 1795331Samw return; 1805331Samw 1815331Samw case HELP_CREATE: 1825331Samw (void) fprintf(fp, gettext("\t%s [-d description] group\n"), 1835331Samw cmd->name); 1845331Samw return; 1855331Samw 1865331Samw case HELP_DELETE: 1875331Samw (void) fprintf(fp, gettext("\t%s group\n"), cmd->name); 1885331Samw return; 1895331Samw 1907052Samw case HELP_USER_DISABLE: 1917052Samw case HELP_USER_ENABLE: 1925331Samw (void) fprintf(fp, gettext("\t%s user\n"), cmd->name); 1935331Samw return; 1945331Samw 1955331Samw case HELP_GET: 1965331Samw (void) fprintf(fp, gettext("\t%s [[-p property] ...] group\n"), 1975331Samw cmd->name); 1985331Samw return; 1995331Samw 2005331Samw case HELP_JOIN: 2015331Samw (void) fprintf(fp, gettext("\t%s -u username domain\n" 2025331Samw "\t%s -w workgroup\n"), cmd->name, cmd->name); 2035331Samw return; 2045331Samw 2055331Samw case HELP_LIST: 2065331Samw (void) fprintf(fp, gettext("\t%s\n"), cmd->name); 2078474SJose.Borrego@Sun.COM (void) fprintf(fp, 2088474SJose.Borrego@Sun.COM gettext("\t\t[*] primary domain\n")); 2098474SJose.Borrego@Sun.COM (void) fprintf(fp, gettext("\t\t[.] local domain\n")); 2108474SJose.Borrego@Sun.COM (void) fprintf(fp, gettext("\t\t[-] other domains\n")); 2118474SJose.Borrego@Sun.COM (void) fprintf(fp, 2128474SJose.Borrego@Sun.COM gettext("\t\t[+] selected domain controller\n")); 2135331Samw return; 2145331Samw 2155331Samw case HELP_DEL_MEMBER: 2165331Samw (void) fprintf(fp, 2175331Samw gettext("\t%s -m member [[-m member] ...] group\n"), 2185331Samw cmd->name); 2195331Samw return; 2205331Samw 2215331Samw case HELP_RENAME: 2225331Samw (void) fprintf(fp, gettext("\t%s group new-group\n"), 2235331Samw cmd->name); 2245331Samw return; 2255331Samw 2265331Samw case HELP_SET: 2275331Samw (void) fprintf(fp, gettext("\t%s -p property=value " 2285331Samw "[[-p property=value] ...] group\n"), cmd->name); 2295331Samw return; 2305331Samw 2315331Samw case HELP_SHOW: 2325331Samw (void) fprintf(fp, gettext("\t%s [-m] [-p] [group]\n"), 2335331Samw cmd->name); 2345331Samw return; 2355331Samw 2367052Samw default: 2377052Samw break; 2385331Samw } 2395331Samw 2405331Samw abort(); 2415331Samw /* NOTREACHED */ 2425331Samw } 2435331Samw 2445331Samw static void 2455331Samw smbadm_usage(boolean_t requested) 2465331Samw { 2475331Samw FILE *fp = requested ? stdout : stderr; 2485331Samw boolean_t show_props = B_FALSE; 2495331Samw int i; 2505331Samw 2515331Samw if (curcmd == NULL) { 2525331Samw (void) fprintf(fp, 2535331Samw gettext("usage: %s [-h | <command> [options]]\n"), 2545331Samw progname); 2555331Samw (void) fprintf(fp, 2565331Samw gettext("where 'command' is one of the following:\n\n")); 2575331Samw 2585331Samw for (i = 0; i < SMBADM_NCMD; i++) 2595331Samw smbadm_cmdusage(fp, &smbadm_cmdtable[i]); 2605331Samw 2615331Samw (void) fprintf(fp, 2625331Samw gettext("\nFor property list, run %s %s|%s\n"), 2635331Samw progname, "get", "set"); 2645331Samw 2655331Samw exit(requested ? 0 : 2); 2665331Samw } 2675331Samw 2685331Samw (void) fprintf(fp, gettext("usage:\n")); 2695331Samw smbadm_cmdusage(fp, curcmd); 2705331Samw 2715331Samw if (strcmp(curcmd->name, "get") == 0 || 2725331Samw strcmp(curcmd->name, "set") == 0) 2735331Samw show_props = B_TRUE; 2745331Samw 2755331Samw if (show_props) { 2765331Samw (void) fprintf(fp, 2775331Samw gettext("\nThe following properties are supported:\n")); 2785331Samw 2795331Samw (void) fprintf(fp, "\n\t%-16s %s\n\n", 2805331Samw "PROPERTY", "VALUES"); 2815331Samw 2825331Samw for (i = 0; i < SMBADM_NPROP; i++) { 2835331Samw (void) fprintf(fp, "\t%-16s %s\n", 2845331Samw smbadm_ptable[i].p_name, 2855331Samw smbadm_ptable[i].p_dispvalue); 2865331Samw } 2875331Samw } 2885331Samw 2895331Samw exit(requested ? 0 : 2); 2905331Samw } 2915331Samw 2925331Samw /* 2937348SJose.Borrego@Sun.COM * smbadm_strcasecmplist 2947348SJose.Borrego@Sun.COM * 2957348SJose.Borrego@Sun.COM * Find a string 's' within a list of strings. 2967348SJose.Borrego@Sun.COM * 2977348SJose.Borrego@Sun.COM * Returns the index of the matching string or -1 if there is no match. 2987348SJose.Borrego@Sun.COM */ 2997348SJose.Borrego@Sun.COM static int 3007348SJose.Borrego@Sun.COM smbadm_strcasecmplist(const char *s, ...) 3017348SJose.Borrego@Sun.COM { 3027348SJose.Borrego@Sun.COM va_list ap; 3037348SJose.Borrego@Sun.COM char *p; 3047348SJose.Borrego@Sun.COM int ndx; 3057348SJose.Borrego@Sun.COM 3067348SJose.Borrego@Sun.COM va_start(ap, s); 3077348SJose.Borrego@Sun.COM 3087348SJose.Borrego@Sun.COM for (ndx = 0; ((p = va_arg(ap, char *)) != NULL); ++ndx) { 3097348SJose.Borrego@Sun.COM if (strcasecmp(s, p) == 0) { 3107348SJose.Borrego@Sun.COM va_end(ap); 3117348SJose.Borrego@Sun.COM return (ndx); 3127348SJose.Borrego@Sun.COM } 3137348SJose.Borrego@Sun.COM } 3147348SJose.Borrego@Sun.COM 3157348SJose.Borrego@Sun.COM va_end(ap); 3167348SJose.Borrego@Sun.COM return (-1); 3177348SJose.Borrego@Sun.COM } 3187348SJose.Borrego@Sun.COM 3197348SJose.Borrego@Sun.COM /* 3207348SJose.Borrego@Sun.COM * smbadm_answer_prompt 3217348SJose.Borrego@Sun.COM * 3227348SJose.Borrego@Sun.COM * Prompt for the answer to a question. A default response must be 3237348SJose.Borrego@Sun.COM * specified, which will be used if the user presses <enter> without 3247348SJose.Borrego@Sun.COM * answering the question. 3257348SJose.Borrego@Sun.COM */ 3267348SJose.Borrego@Sun.COM static int 3277348SJose.Borrego@Sun.COM smbadm_answer_prompt(const char *prompt, char *answer, const char *dflt) 3287348SJose.Borrego@Sun.COM { 3297348SJose.Borrego@Sun.COM char buf[SMBADM_ANSBUFSIZ]; 3307348SJose.Borrego@Sun.COM char *p; 3317348SJose.Borrego@Sun.COM 3327348SJose.Borrego@Sun.COM (void) printf(gettext("%s [%s]: "), prompt, dflt); 3337348SJose.Borrego@Sun.COM 3347348SJose.Borrego@Sun.COM if (fgets(buf, SMBADM_ANSBUFSIZ, stdin) == NULL) 3357348SJose.Borrego@Sun.COM return (-1); 3367348SJose.Borrego@Sun.COM 3377348SJose.Borrego@Sun.COM if ((p = strchr(buf, '\n')) != NULL) 3387348SJose.Borrego@Sun.COM *p = '\0'; 3397348SJose.Borrego@Sun.COM 3407348SJose.Borrego@Sun.COM if (*buf == '\0') 3417348SJose.Borrego@Sun.COM (void) strlcpy(answer, dflt, SMBADM_ANSBUFSIZ); 3427348SJose.Borrego@Sun.COM else 3437348SJose.Borrego@Sun.COM (void) strlcpy(answer, buf, SMBADM_ANSBUFSIZ); 3447348SJose.Borrego@Sun.COM 3457348SJose.Borrego@Sun.COM return (0); 3467348SJose.Borrego@Sun.COM } 3477348SJose.Borrego@Sun.COM 3487348SJose.Borrego@Sun.COM /* 3497348SJose.Borrego@Sun.COM * smbadm_confirm 3507348SJose.Borrego@Sun.COM * 3517348SJose.Borrego@Sun.COM * Ask a question that requires a yes/no answer. 3527348SJose.Borrego@Sun.COM * A default response must be specified. 3537348SJose.Borrego@Sun.COM */ 3547348SJose.Borrego@Sun.COM static boolean_t 3557348SJose.Borrego@Sun.COM smbadm_confirm(const char *prompt, const char *dflt) 3567348SJose.Borrego@Sun.COM { 3577348SJose.Borrego@Sun.COM char buf[SMBADM_ANSBUFSIZ]; 3587348SJose.Borrego@Sun.COM 3597348SJose.Borrego@Sun.COM for (;;) { 3607348SJose.Borrego@Sun.COM if (smbadm_answer_prompt(prompt, buf, dflt) < 0) 3617348SJose.Borrego@Sun.COM return (B_FALSE); 3627348SJose.Borrego@Sun.COM 3637348SJose.Borrego@Sun.COM if (smbadm_strcasecmplist(buf, "n", "no", 0) >= 0) 3647348SJose.Borrego@Sun.COM return (B_FALSE); 3657348SJose.Borrego@Sun.COM 3667348SJose.Borrego@Sun.COM if (smbadm_strcasecmplist(buf, "y", "yes", 0) >= 0) 3677348SJose.Borrego@Sun.COM return (B_TRUE); 3687348SJose.Borrego@Sun.COM 3697348SJose.Borrego@Sun.COM (void) printf(gettext("Please answer yes or no.\n")); 3707348SJose.Borrego@Sun.COM } 3717348SJose.Borrego@Sun.COM } 3727348SJose.Borrego@Sun.COM 3737348SJose.Borrego@Sun.COM static boolean_t 3748334SJose.Borrego@Sun.COM smbadm_join_prompt(const char *domain) 3757348SJose.Borrego@Sun.COM { 3768334SJose.Borrego@Sun.COM (void) printf(gettext("After joining %s the smb service will be " 3778334SJose.Borrego@Sun.COM "restarted automatically.\n"), domain); 3787348SJose.Borrego@Sun.COM 3798334SJose.Borrego@Sun.COM return (smbadm_confirm("Would you like to continue?", "no")); 3808334SJose.Borrego@Sun.COM } 3817348SJose.Borrego@Sun.COM 3828334SJose.Borrego@Sun.COM static void 3838334SJose.Borrego@Sun.COM smbadm_restart_service(void) 3848334SJose.Borrego@Sun.COM { 3858334SJose.Borrego@Sun.COM if (smb_smf_restart_service() != 0) { 3868334SJose.Borrego@Sun.COM (void) fprintf(stderr, 3878334SJose.Borrego@Sun.COM gettext("Unable to restart smb service. " 3888334SJose.Borrego@Sun.COM "Run 'svcs -xv smb/server' for more information.")); 3897348SJose.Borrego@Sun.COM } 3907348SJose.Borrego@Sun.COM } 3917348SJose.Borrego@Sun.COM 3927348SJose.Borrego@Sun.COM /* 3935331Samw * smbadm_join 3945331Samw * 3958334SJose.Borrego@Sun.COM * Join a domain or workgroup. 3968334SJose.Borrego@Sun.COM * 3978334SJose.Borrego@Sun.COM * When joining a domain, we may receive the username, password and 3988334SJose.Borrego@Sun.COM * domain name in any of the following combinations. Note that the 3998334SJose.Borrego@Sun.COM * password is optional on the command line: if it is not provided, 4008334SJose.Borrego@Sun.COM * we will prompt for it later. 4018334SJose.Borrego@Sun.COM * 4028334SJose.Borrego@Sun.COM * username+password domain 4038334SJose.Borrego@Sun.COM * domain\username+password 4048334SJose.Borrego@Sun.COM * domain/username+password 4058334SJose.Borrego@Sun.COM * username@domain 4068334SJose.Borrego@Sun.COM * 4078334SJose.Borrego@Sun.COM * We allow domain\name+password or domain/name+password but not 4088334SJose.Borrego@Sun.COM * name+password@domain because @ is a valid password character. 4098334SJose.Borrego@Sun.COM * 4108334SJose.Borrego@Sun.COM * If the username and domain name are passed as separate command 4118334SJose.Borrego@Sun.COM * line arguments, we process them directly. Otherwise we separate 4128334SJose.Borrego@Sun.COM * them and continue as if they were separate command line arguments. 4135331Samw */ 4145331Samw static int 4155331Samw smbadm_join(int argc, char **argv) 4165331Samw { 4178334SJose.Borrego@Sun.COM char buf[MAXHOSTNAMELEN * 2]; 4188334SJose.Borrego@Sun.COM char *domain = NULL; 4198334SJose.Borrego@Sun.COM char *username = NULL; 4208334SJose.Borrego@Sun.COM uint32_t mode = 0; 4215331Samw char option; 4225331Samw 4235331Samw while ((option = getopt(argc, argv, "u:w:")) != -1) { 4245331Samw switch (option) { 4255331Samw case 'w': 4268334SJose.Borrego@Sun.COM if (mode != 0) { 4278334SJose.Borrego@Sun.COM (void) fprintf(stderr, 4288334SJose.Borrego@Sun.COM gettext("-u and -w must only appear " 4298334SJose.Borrego@Sun.COM "once and are mutually exclusive\n")); 4308334SJose.Borrego@Sun.COM smbadm_usage(B_FALSE); 4318334SJose.Borrego@Sun.COM } 4328334SJose.Borrego@Sun.COM 4338334SJose.Borrego@Sun.COM mode = SMB_SECMODE_WORKGRP; 4348334SJose.Borrego@Sun.COM domain = optarg; 4355331Samw break; 4365331Samw 4375331Samw case 'u': 4388334SJose.Borrego@Sun.COM if (mode != 0) { 4398334SJose.Borrego@Sun.COM (void) fprintf(stderr, 4408334SJose.Borrego@Sun.COM gettext("-u and -w must only appear " 4418334SJose.Borrego@Sun.COM "once and are mutually exclusive\n")); 4428334SJose.Borrego@Sun.COM smbadm_usage(B_FALSE); 4438334SJose.Borrego@Sun.COM } 4448334SJose.Borrego@Sun.COM 4458334SJose.Borrego@Sun.COM mode = SMB_SECMODE_DOMAIN; 4468334SJose.Borrego@Sun.COM username = optarg; 4478334SJose.Borrego@Sun.COM 4488334SJose.Borrego@Sun.COM if ((domain = argv[optind]) == NULL) { 4498334SJose.Borrego@Sun.COM /* 4508334SJose.Borrego@Sun.COM * The domain was not specified as a separate 4518334SJose.Borrego@Sun.COM * argument, check for the combination forms. 4528334SJose.Borrego@Sun.COM */ 4538334SJose.Borrego@Sun.COM (void) strlcpy(buf, username, sizeof (buf)); 4548334SJose.Borrego@Sun.COM smbadm_extract_domain(buf, &username, &domain); 4558334SJose.Borrego@Sun.COM } 4568334SJose.Borrego@Sun.COM 4578334SJose.Borrego@Sun.COM if ((username == NULL) || (*username == '\0')) { 4588334SJose.Borrego@Sun.COM (void) fprintf(stderr, 4598334SJose.Borrego@Sun.COM gettext("missing username\n")); 4608334SJose.Borrego@Sun.COM smbadm_usage(B_FALSE); 4618334SJose.Borrego@Sun.COM } 4625331Samw break; 4635331Samw 4645331Samw default: 4655331Samw smbadm_usage(B_FALSE); 4668334SJose.Borrego@Sun.COM break; 4675331Samw } 4685331Samw } 4695331Samw 4708334SJose.Borrego@Sun.COM if ((domain == NULL) || (*domain == '\0')) { 4718334SJose.Borrego@Sun.COM (void) fprintf(stderr, gettext("missing %s name\n"), 4728334SJose.Borrego@Sun.COM (mode == SMB_SECMODE_WORKGRP) ? "workgroup" : "domain"); 4735331Samw smbadm_usage(B_FALSE); 4745331Samw } 4755331Samw 4768334SJose.Borrego@Sun.COM if (mode == SMB_SECMODE_WORKGRP) 4778334SJose.Borrego@Sun.COM return (smbadm_join_workgroup(domain)); 4788334SJose.Borrego@Sun.COM else 4798334SJose.Borrego@Sun.COM return (smbadm_join_domain(domain, username)); 4808334SJose.Borrego@Sun.COM } 4815331Samw 4828334SJose.Borrego@Sun.COM /* 4838334SJose.Borrego@Sun.COM * Workgroups comprise a collection of standalone, independently administered 4848334SJose.Borrego@Sun.COM * computers that use a common workgroup name. This is a peer-to-peer model 4858334SJose.Borrego@Sun.COM * with no formal membership mechanism. 4868334SJose.Borrego@Sun.COM */ 4878334SJose.Borrego@Sun.COM static int 4888334SJose.Borrego@Sun.COM smbadm_join_workgroup(const char *workgroup) 4898334SJose.Borrego@Sun.COM { 4908334SJose.Borrego@Sun.COM smb_joininfo_t jdi; 4918334SJose.Borrego@Sun.COM uint32_t status; 4925331Samw 4938334SJose.Borrego@Sun.COM bzero(&jdi, sizeof (jdi)); 4948334SJose.Borrego@Sun.COM jdi.mode = SMB_SECMODE_WORKGRP; 4958334SJose.Borrego@Sun.COM (void) strlcpy(jdi.domain_name, workgroup, sizeof (jdi.domain_name)); 4968334SJose.Borrego@Sun.COM (void) strtrim(jdi.domain_name, " \t\n"); 4978334SJose.Borrego@Sun.COM 498*11337SWilliam.Krier@Sun.COM if (smb_name_validate_workgroup(jdi.domain_name) != ERROR_SUCCESS) { 4998334SJose.Borrego@Sun.COM (void) fprintf(stderr, gettext("workgroup name is invalid\n")); 5005331Samw smbadm_usage(B_FALSE); 5015331Samw } 5025331Samw 5038334SJose.Borrego@Sun.COM if (!smbadm_join_prompt(jdi.domain_name)) 5048334SJose.Borrego@Sun.COM return (0); 5057348SJose.Borrego@Sun.COM 5068334SJose.Borrego@Sun.COM if ((status = smb_join(&jdi)) != NT_STATUS_SUCCESS) { 5078334SJose.Borrego@Sun.COM (void) fprintf(stderr, gettext("failed to join %s: %s\n"), 5085331Samw jdi.domain_name, xlate_nt_status(status)); 5095331Samw return (1); 5105331Samw } 5115331Samw 5128334SJose.Borrego@Sun.COM (void) printf(gettext("Successfully joined %s\n"), jdi.domain_name); 5138334SJose.Borrego@Sun.COM smbadm_restart_service(); 5148334SJose.Borrego@Sun.COM return (0); 5158334SJose.Borrego@Sun.COM } 5168334SJose.Borrego@Sun.COM 5178334SJose.Borrego@Sun.COM /* 5188334SJose.Borrego@Sun.COM * Domains comprise a centrally administered group of computers and accounts 5198334SJose.Borrego@Sun.COM * that share a common security and administration policy and database. 5208334SJose.Borrego@Sun.COM * Computers must join a domain and become domain members, which requires 5218334SJose.Borrego@Sun.COM * an administrator level account name. 5228334SJose.Borrego@Sun.COM * 5238334SJose.Borrego@Sun.COM * The '+' character is invalid within a username. We allow the password 5248334SJose.Borrego@Sun.COM * to be appended to the username using '+' as a scripting convenience. 5258334SJose.Borrego@Sun.COM */ 5268334SJose.Borrego@Sun.COM static int 5278334SJose.Borrego@Sun.COM smbadm_join_domain(const char *domain, const char *username) 5288334SJose.Borrego@Sun.COM { 5298334SJose.Borrego@Sun.COM smb_joininfo_t jdi; 5308334SJose.Borrego@Sun.COM uint32_t status; 5318334SJose.Borrego@Sun.COM char *prompt; 5328334SJose.Borrego@Sun.COM char *p; 5338334SJose.Borrego@Sun.COM int len; 5348334SJose.Borrego@Sun.COM 5358334SJose.Borrego@Sun.COM bzero(&jdi, sizeof (jdi)); 5368334SJose.Borrego@Sun.COM jdi.mode = SMB_SECMODE_DOMAIN; 5378334SJose.Borrego@Sun.COM (void) strlcpy(jdi.domain_name, domain, sizeof (jdi.domain_name)); 5388334SJose.Borrego@Sun.COM (void) strtrim(jdi.domain_name, " \t\n"); 5398334SJose.Borrego@Sun.COM 540*11337SWilliam.Krier@Sun.COM if (smb_name_validate_domain(jdi.domain_name) != ERROR_SUCCESS) { 5418334SJose.Borrego@Sun.COM (void) fprintf(stderr, gettext("domain name is invalid\n")); 5428334SJose.Borrego@Sun.COM smbadm_usage(B_FALSE); 5436139Sjb150015 } 5446139Sjb150015 5458334SJose.Borrego@Sun.COM if (!smbadm_join_prompt(jdi.domain_name)) 5468334SJose.Borrego@Sun.COM return (0); 5478334SJose.Borrego@Sun.COM 5488334SJose.Borrego@Sun.COM if ((p = strchr(username, '+')) != NULL) { 5498334SJose.Borrego@Sun.COM ++p; 5508334SJose.Borrego@Sun.COM 5518334SJose.Borrego@Sun.COM len = (int)(p - username); 5528334SJose.Borrego@Sun.COM if (len > sizeof (jdi.domain_name)) 5538334SJose.Borrego@Sun.COM len = sizeof (jdi.domain_name); 5547348SJose.Borrego@Sun.COM 5558334SJose.Borrego@Sun.COM (void) strlcpy(jdi.domain_username, username, len); 5568334SJose.Borrego@Sun.COM (void) strlcpy(jdi.domain_passwd, p, 5578334SJose.Borrego@Sun.COM sizeof (jdi.domain_passwd)); 5588334SJose.Borrego@Sun.COM } else { 5598334SJose.Borrego@Sun.COM (void) strlcpy(jdi.domain_username, username, 5608334SJose.Borrego@Sun.COM sizeof (jdi.domain_username)); 5618334SJose.Borrego@Sun.COM } 5628334SJose.Borrego@Sun.COM 563*11337SWilliam.Krier@Sun.COM if (smb_name_validate_account(jdi.domain_username) != ERROR_SUCCESS) { 5648334SJose.Borrego@Sun.COM (void) fprintf(stderr, 5658334SJose.Borrego@Sun.COM gettext("username contains invalid characters\n")); 5668334SJose.Borrego@Sun.COM smbadm_usage(B_FALSE); 5678334SJose.Borrego@Sun.COM } 5688334SJose.Borrego@Sun.COM 5695331Samw if (*jdi.domain_passwd == '\0') { 5708334SJose.Borrego@Sun.COM prompt = gettext("Enter domain password: "); 5718334SJose.Borrego@Sun.COM 5728334SJose.Borrego@Sun.COM if ((p = getpassphrase(prompt)) == NULL) { 5735331Samw (void) fprintf(stderr, gettext("missing password\n")); 5745331Samw smbadm_usage(B_FALSE); 5755331Samw } 5765331Samw 5775331Samw (void) strlcpy(jdi.domain_passwd, p, 5785331Samw sizeof (jdi.domain_passwd)); 5795331Samw } 5805331Samw 5818334SJose.Borrego@Sun.COM (void) printf(gettext("Joining %s ... this may take a minute ...\n"), 5825331Samw jdi.domain_name); 5835331Samw 5845331Samw status = smb_join(&jdi); 5855331Samw 5865331Samw switch (status) { 5875331Samw case NT_STATUS_SUCCESS: 5888334SJose.Borrego@Sun.COM (void) printf(gettext("Successfully joined %s\n"), 5895331Samw jdi.domain_name); 5908334SJose.Borrego@Sun.COM bzero(&jdi, sizeof (jdi)); 5918334SJose.Borrego@Sun.COM smbadm_restart_service(); 5925331Samw return (0); 5935331Samw 5945331Samw case NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND: 5958334SJose.Borrego@Sun.COM (void) fprintf(stderr, 5968334SJose.Borrego@Sun.COM gettext("failed to find any domain controllers for %s\n"), 5975331Samw jdi.domain_name); 5988334SJose.Borrego@Sun.COM bzero(&jdi, sizeof (jdi)); 5998334SJose.Borrego@Sun.COM return (1); 6005331Samw 6015331Samw default: 6028334SJose.Borrego@Sun.COM (void) fprintf(stderr, gettext("failed to join %s: %s\n"), 6035331Samw jdi.domain_name, xlate_nt_status(status)); 6049021Samw@Sun.COM (void) fprintf(stderr, gettext("Please refer to the system log" 6059021Samw@Sun.COM " for more information.\n")); 6068334SJose.Borrego@Sun.COM bzero(&jdi, sizeof (jdi)); 6078334SJose.Borrego@Sun.COM return (1); 6088334SJose.Borrego@Sun.COM } 6098334SJose.Borrego@Sun.COM } 6108334SJose.Borrego@Sun.COM 6118334SJose.Borrego@Sun.COM /* 6128334SJose.Borrego@Sun.COM * We want to process the user and domain names as separate strings. 6138334SJose.Borrego@Sun.COM * Check for names of the forms below and separate the components as 6148334SJose.Borrego@Sun.COM * required. 6158334SJose.Borrego@Sun.COM * 6168334SJose.Borrego@Sun.COM * name@domain 6178334SJose.Borrego@Sun.COM * domain\name 6188334SJose.Borrego@Sun.COM * domain/name 6198334SJose.Borrego@Sun.COM * 6208334SJose.Borrego@Sun.COM * If we encounter any of the forms above in arg, the @, / or \ 6218334SJose.Borrego@Sun.COM * separator is replaced by \0 and the username and domain pointers 6228334SJose.Borrego@Sun.COM * are changed to point to the appropriate components (in arg). 6238334SJose.Borrego@Sun.COM * 6248334SJose.Borrego@Sun.COM * If none of the separators are encountered, the username and domain 6258334SJose.Borrego@Sun.COM * pointers remain unchanged. 6268334SJose.Borrego@Sun.COM */ 6278334SJose.Borrego@Sun.COM static void 6288334SJose.Borrego@Sun.COM smbadm_extract_domain(char *arg, char **username, char **domain) 6298334SJose.Borrego@Sun.COM { 6308334SJose.Borrego@Sun.COM char *p; 6318334SJose.Borrego@Sun.COM 6328334SJose.Borrego@Sun.COM if ((p = strpbrk(arg, "/\\@")) != NULL) { 6338334SJose.Borrego@Sun.COM if (*p == '@') { 6348334SJose.Borrego@Sun.COM *p = '\0'; 6358334SJose.Borrego@Sun.COM ++p; 6368334SJose.Borrego@Sun.COM 6378334SJose.Borrego@Sun.COM if (strchr(arg, '+') != NULL) 6388334SJose.Borrego@Sun.COM return; 6398334SJose.Borrego@Sun.COM 6408334SJose.Borrego@Sun.COM *domain = p; 6418334SJose.Borrego@Sun.COM *username = arg; 6428334SJose.Borrego@Sun.COM } else { 6438334SJose.Borrego@Sun.COM *p = '\0'; 6448334SJose.Borrego@Sun.COM ++p; 6458334SJose.Borrego@Sun.COM *username = p; 6468334SJose.Borrego@Sun.COM *domain = arg; 6478334SJose.Borrego@Sun.COM } 6488334SJose.Borrego@Sun.COM } 6498334SJose.Borrego@Sun.COM } 6508334SJose.Borrego@Sun.COM 6518334SJose.Borrego@Sun.COM /* 6525331Samw * smbadm_list 6535331Samw * 6545331Samw * Displays current security mode and domain/workgroup name. 6555331Samw */ 6565331Samw /*ARGSUSED*/ 6575331Samw static int 6585331Samw smbadm_list(int argc, char **argv) 6595331Samw { 6606139Sjb150015 char domain[MAXHOSTNAMELEN]; 6618334SJose.Borrego@Sun.COM char fqdn[MAXHOSTNAMELEN]; 6628334SJose.Borrego@Sun.COM char srvname[MAXHOSTNAMELEN]; 6636139Sjb150015 char modename[16]; 6646139Sjb150015 int rc; 6658670SJose.Borrego@Sun.COM smb_inaddr_t srvipaddr; 6667348SJose.Borrego@Sun.COM char ipstr[INET6_ADDRSTRLEN]; 6675331Samw 6686139Sjb150015 rc = smb_config_getstr(SMB_CI_SECURITY, modename, sizeof (modename)); 6696139Sjb150015 if (rc != SMBD_SMF_OK) { 6705331Samw (void) fprintf(stderr, 6718474SJose.Borrego@Sun.COM gettext("cannot determine the operational mode\n")); 6725331Samw return (1); 6735331Samw } 6745331Samw 6756139Sjb150015 if (smb_getdomainname(domain, sizeof (domain)) != 0) { 6766139Sjb150015 (void) fprintf(stderr, gettext("failed to get the %s name\n"), 6776139Sjb150015 modename); 6785331Samw return (1); 6795331Samw } 6808474SJose.Borrego@Sun.COM 6817348SJose.Borrego@Sun.COM if (strcmp(modename, "workgroup") == 0) { 6828474SJose.Borrego@Sun.COM (void) printf(gettext("[*] [%s]\n"), domain); 6837348SJose.Borrego@Sun.COM return (0); 6847348SJose.Borrego@Sun.COM } 6858474SJose.Borrego@Sun.COM 6868474SJose.Borrego@Sun.COM (void) printf(gettext("[*] [%s]\n"), domain); 6878334SJose.Borrego@Sun.COM if ((smb_getfqdomainname(fqdn, sizeof (fqdn)) == 0) && (*fqdn != '\0')) 6888474SJose.Borrego@Sun.COM (void) printf(gettext("[*] [%s]\n"), fqdn); 6895331Samw 6908334SJose.Borrego@Sun.COM if ((smb_get_dcinfo(srvname, MAXHOSTNAMELEN, &srvipaddr) 6918334SJose.Borrego@Sun.COM == NT_STATUS_SUCCESS) && (*srvname != '\0') && 6928670SJose.Borrego@Sun.COM (!smb_inet_iszero(&srvipaddr))) { 6938670SJose.Borrego@Sun.COM (void) smb_inet_ntop(&srvipaddr, ipstr, 6948670SJose.Borrego@Sun.COM SMB_IPSTRLEN(srvipaddr.a_family)); 6958474SJose.Borrego@Sun.COM (void) printf(gettext("\t[+%s.%s] [%s]\n"), 6968474SJose.Borrego@Sun.COM srvname, fqdn, ipstr); 6977348SJose.Borrego@Sun.COM } 6988474SJose.Borrego@Sun.COM 69910717Samw@Sun.COM smb_domain_show(); 7005331Samw return (0); 7015331Samw } 7025331Samw 7035331Samw /* 7045331Samw * smbadm_group_create 7055331Samw * 7065331Samw * Creates a local SMB group 7075331Samw */ 7085331Samw static int 7095331Samw smbadm_group_create(int argc, char **argv) 7105331Samw { 7115331Samw char *gname = NULL; 7125331Samw char *desc = NULL; 7135331Samw char option; 7145772Sas200622 int status; 7155331Samw 7165331Samw while ((option = getopt(argc, argv, "d:")) != -1) { 7175331Samw switch (option) { 7185331Samw case 'd': 7195331Samw desc = optarg; 7205331Samw break; 7215331Samw 7225331Samw default: 7235331Samw smbadm_usage(B_FALSE); 7245331Samw } 7255331Samw } 7265331Samw 7275331Samw gname = argv[optind]; 7285331Samw if (optind >= argc || gname == NULL || *gname == '\0') { 7295331Samw (void) fprintf(stderr, gettext("missing group name\n")); 7305331Samw smbadm_usage(B_FALSE); 7315331Samw } 7325331Samw 7335331Samw if (getgrnam(gname) == NULL) { 7345331Samw (void) fprintf(stderr, 7355772Sas200622 gettext("failed to get the Solaris group '%s'\n"), gname); 7365331Samw (void) fprintf(stderr, 7375772Sas200622 gettext("use 'groupadd' to add '%s'\n"), gname); 7385331Samw return (1); 7395331Samw } 7405331Samw 7415772Sas200622 status = smb_lgrp_add(gname, desc); 7425772Sas200622 if (status != SMB_LGRP_SUCCESS) { 7435331Samw (void) fprintf(stderr, 7445331Samw gettext("failed to create the group (%s)\n"), 7455772Sas200622 smb_lgrp_strerror(status)); 7465331Samw } else { 7475772Sas200622 (void) printf(gettext("'%s' created.\n"), 7485331Samw gname); 7495331Samw } 7505331Samw 7515331Samw return (status); 7525331Samw } 7535331Samw 7545331Samw /* 7555331Samw * smbadm_group_dump_members 7565331Samw * 7575331Samw * Dump group members details. 7585331Samw */ 7595331Samw static void 7605772Sas200622 smbadm_group_dump_members(smb_gsid_t *members, int num) 7615331Samw { 762*11337SWilliam.Krier@Sun.COM char sidstr[SMB_SID_STRSZ]; 763*11337SWilliam.Krier@Sun.COM lsa_account_t acct; 764*11337SWilliam.Krier@Sun.COM int i; 7655331Samw 7665772Sas200622 if (num == 0) { 7675331Samw (void) printf(gettext("\tNo members\n")); 7685331Samw return; 7695331Samw } 7705331Samw 7715331Samw (void) printf(gettext("\tMembers:\n")); 7725772Sas200622 for (i = 0; i < num; i++) { 773*11337SWilliam.Krier@Sun.COM smb_sid_tostr(members[i].gs_sid, sidstr); 774*11337SWilliam.Krier@Sun.COM 775*11337SWilliam.Krier@Sun.COM if (smb_lookup_sid(sidstr, &acct) == 0) { 776*11337SWilliam.Krier@Sun.COM if (acct.a_status == NT_STATUS_SUCCESS) 777*11337SWilliam.Krier@Sun.COM smbadm_group_show_name(acct.a_domain, 778*11337SWilliam.Krier@Sun.COM acct.a_name); 779*11337SWilliam.Krier@Sun.COM else 780*11337SWilliam.Krier@Sun.COM (void) printf(gettext("\t\t%s [%s]\n"), 781*11337SWilliam.Krier@Sun.COM sidstr, xlate_nt_status(acct.a_status)); 782*11337SWilliam.Krier@Sun.COM } else { 7836600Sas200622 (void) printf(gettext("\t\t%s\n"), sidstr); 784*11337SWilliam.Krier@Sun.COM } 7855331Samw } 7865331Samw } 7875331Samw 788*11337SWilliam.Krier@Sun.COM static void 789*11337SWilliam.Krier@Sun.COM smbadm_group_show_name(const char *domain, const char *name) 790*11337SWilliam.Krier@Sun.COM { 791*11337SWilliam.Krier@Sun.COM if (strchr(domain, '.') != NULL) 792*11337SWilliam.Krier@Sun.COM (void) printf(gettext("\t\t%s@%s\n"), name, domain); 793*11337SWilliam.Krier@Sun.COM else 794*11337SWilliam.Krier@Sun.COM (void) printf(gettext("\t\t%s\\%s\n"), domain, name); 795*11337SWilliam.Krier@Sun.COM } 796*11337SWilliam.Krier@Sun.COM 7975331Samw /* 7985331Samw * smbadm_group_dump_privs 7995331Samw * 8005331Samw * Dump group privilege details. 8015331Samw */ 8025331Samw static void 8035772Sas200622 smbadm_group_dump_privs(smb_privset_t *privs) 8045331Samw { 8055772Sas200622 smb_privinfo_t *pinfo; 8065772Sas200622 char *pstatus; 8075331Samw int i; 8085331Samw 8095331Samw (void) printf(gettext("\tPrivileges: \n")); 8105331Samw 8115772Sas200622 for (i = 0; i < privs->priv_cnt; i++) { 8125772Sas200622 pinfo = smb_priv_getbyvalue(privs->priv[i].luid.lo_part); 8135772Sas200622 if ((pinfo == NULL) || (pinfo->flags & PF_PRESENTABLE) == 0) 8145331Samw continue; 8155331Samw 8165772Sas200622 switch (privs->priv[i].attrs) { 8175772Sas200622 case SE_PRIVILEGE_ENABLED: 8185772Sas200622 pstatus = "On"; 8195772Sas200622 break; 8205772Sas200622 case SE_PRIVILEGE_DISABLED: 8215772Sas200622 pstatus = "Off"; 8225772Sas200622 break; 8235772Sas200622 default: 8245772Sas200622 pstatus = "Unknown"; 8255772Sas200622 break; 8265331Samw } 8275772Sas200622 (void) printf(gettext("\t\t%s: %s\n"), pinfo->name, pstatus); 8285331Samw } 8295331Samw 8305772Sas200622 if (privs->priv_cnt == 0) 8315331Samw (void) printf(gettext("\t\tNo privileges\n")); 8325331Samw } 8335331Samw 8345331Samw /* 8355331Samw * smbadm_group_dump 8365331Samw * 8375331Samw * Dump group details. 8385331Samw */ 8395772Sas200622 static void 8405772Sas200622 smbadm_group_dump(smb_group_t *grp, boolean_t show_mem, boolean_t show_privs) 8415331Samw { 8426432Sas200622 char sidstr[SMB_SID_STRSZ]; 8435331Samw 8445772Sas200622 (void) printf(gettext("%s (%s)\n"), grp->sg_name, grp->sg_cmnt); 8455331Samw 8466432Sas200622 smb_sid_tostr(grp->sg_id.gs_sid, sidstr); 8475772Sas200622 (void) printf(gettext("\tSID: %s\n"), sidstr); 8485331Samw 8495772Sas200622 if (show_privs) 8505772Sas200622 smbadm_group_dump_privs(grp->sg_privs); 8515331Samw 8525772Sas200622 if (show_mem) 8535772Sas200622 smbadm_group_dump_members(grp->sg_members, grp->sg_nmembers); 8545331Samw } 8555331Samw 8565331Samw /* 8575331Samw * smbadm_group_show 8585331Samw * 8595331Samw */ 8605331Samw static int 8615331Samw smbadm_group_show(int argc, char **argv) 8625331Samw { 8635331Samw char *gname = NULL; 8645331Samw boolean_t show_privs; 8655331Samw boolean_t show_members; 8665331Samw char option; 8675772Sas200622 int status; 8685772Sas200622 smb_group_t grp; 8695772Sas200622 smb_giter_t gi; 8705331Samw 8715331Samw show_privs = show_members = B_FALSE; 8725331Samw 8735331Samw while ((option = getopt(argc, argv, "mp")) != -1) { 8745331Samw switch (option) { 8755331Samw case 'm': 8765331Samw show_members = B_TRUE; 8775331Samw break; 8785331Samw case 'p': 8795331Samw show_privs = B_TRUE; 8805331Samw break; 8815331Samw 8825331Samw default: 8835331Samw smbadm_usage(B_FALSE); 8845331Samw } 8855331Samw } 8865331Samw 8875331Samw gname = argv[optind]; 8885331Samw if (optind >= argc || gname == NULL || *gname == '\0') 8895331Samw gname = "*"; 8905331Samw 8915772Sas200622 if (strcmp(gname, "*")) { 8925772Sas200622 status = smb_lgrp_getbyname(gname, &grp); 8935772Sas200622 if (status == SMB_LGRP_SUCCESS) { 8945772Sas200622 smbadm_group_dump(&grp, show_members, show_privs); 8955772Sas200622 smb_lgrp_free(&grp); 8965772Sas200622 } else { 8975772Sas200622 (void) fprintf(stderr, 8988334SJose.Borrego@Sun.COM gettext("failed to find %s (%s)\n"), 8995772Sas200622 gname, smb_lgrp_strerror(status)); 9005772Sas200622 } 9015772Sas200622 return (status); 9025331Samw } 9035331Samw 9046432Sas200622 if ((status = smb_lgrp_iteropen(&gi)) != SMB_LGRP_SUCCESS) { 9058334SJose.Borrego@Sun.COM (void) fprintf(stderr, gettext("failed to list groups (%s)\n"), 9065772Sas200622 smb_lgrp_strerror(status)); 9075772Sas200622 return (status); 9085331Samw } 9095331Samw 9106432Sas200622 while ((status = smb_lgrp_iterate(&gi, &grp)) == SMB_LGRP_SUCCESS) { 9115772Sas200622 smbadm_group_dump(&grp, show_members, show_privs); 9125772Sas200622 smb_lgrp_free(&grp); 9135772Sas200622 } 9146432Sas200622 9155772Sas200622 smb_lgrp_iterclose(&gi); 9165772Sas200622 9176432Sas200622 if (status != SMB_LGRP_NO_MORE) { 9186432Sas200622 (void) fprintf(stderr, 9196432Sas200622 gettext("failed to get all the groups (%s)\n"), 9206432Sas200622 smb_lgrp_strerror(status)); 9216432Sas200622 return (status); 9226432Sas200622 } 9236432Sas200622 9245772Sas200622 return (0); 9255331Samw } 9265331Samw 9275331Samw /* 9285331Samw * smbadm_group_delete 9295331Samw */ 9305331Samw static int 9315331Samw smbadm_group_delete(int argc, char **argv) 9325331Samw { 9335331Samw char *gname = NULL; 9345772Sas200622 int status; 9355331Samw 9365331Samw gname = argv[optind]; 9375331Samw if (optind >= argc || gname == NULL || *gname == '\0') { 9385331Samw (void) fprintf(stderr, gettext("missing group name\n")); 9395331Samw smbadm_usage(B_FALSE); 9405331Samw } 9415331Samw 9425772Sas200622 status = smb_lgrp_delete(gname); 9435772Sas200622 if (status != SMB_LGRP_SUCCESS) { 9445331Samw (void) fprintf(stderr, 9458334SJose.Borrego@Sun.COM gettext("failed to delete %s (%s)\n"), gname, 9465772Sas200622 smb_lgrp_strerror(status)); 9475331Samw } else { 9488334SJose.Borrego@Sun.COM (void) printf(gettext("%s deleted.\n"), gname); 9495331Samw } 9505331Samw 9515331Samw return (status); 9525331Samw } 9535331Samw 9545331Samw /* 9555331Samw * smbadm_group_rename 9565331Samw */ 9575331Samw static int 9585331Samw smbadm_group_rename(int argc, char **argv) 9595331Samw { 9605331Samw char *gname = NULL; 9615331Samw char *ngname = NULL; 9625772Sas200622 int status; 9635331Samw 9645331Samw gname = argv[optind]; 9655331Samw if (optind++ >= argc || gname == NULL || *gname == '\0') { 9665331Samw (void) fprintf(stderr, gettext("missing group name\n")); 9675331Samw smbadm_usage(B_FALSE); 9685331Samw } 9695331Samw 9705331Samw ngname = argv[optind]; 9715331Samw if (optind >= argc || ngname == NULL || *ngname == '\0') { 9725331Samw (void) fprintf(stderr, gettext("missing new group name\n")); 9735331Samw smbadm_usage(B_FALSE); 9745331Samw } 9755331Samw 9765772Sas200622 if (getgrnam(ngname) == NULL) { 9775331Samw (void) fprintf(stderr, 9785772Sas200622 gettext("failed to get the Solaris group '%s'\n"), ngname); 9795331Samw (void) fprintf(stderr, 9805772Sas200622 gettext("use 'groupadd' to add '%s'\n"), ngname); 9815331Samw return (1); 9825331Samw } 9835331Samw 9845772Sas200622 status = smb_lgrp_rename(gname, ngname); 9855772Sas200622 if (status != SMB_LGRP_SUCCESS) { 9865772Sas200622 if (status == SMB_LGRP_EXISTS) 9875772Sas200622 (void) fprintf(stderr, 9885772Sas200622 gettext("failed to rename '%s' (%s already " 9895772Sas200622 "exists)\n"), gname, ngname); 9905772Sas200622 else 9915772Sas200622 (void) fprintf(stderr, 9925772Sas200622 gettext("failed to rename '%s' (%s)\n"), gname, 9935772Sas200622 smb_lgrp_strerror(status)); 9945331Samw } else { 9955772Sas200622 (void) printf(gettext("'%s' renamed to '%s'\n"), gname, ngname); 9965331Samw } 9975331Samw 9985331Samw return (status); 9995331Samw } 10005331Samw 10015331Samw /* 10025331Samw * smbadm_group_setprop 10035331Samw * 10045331Samw * Set the group properties. 10055331Samw */ 10065331Samw static int 10075331Samw smbadm_group_setprop(int argc, char **argv) 10085331Samw { 10095331Samw char *gname = NULL; 10105331Samw smbadm_prop_t props[SMBADM_NPROP]; 10115331Samw smbadm_prop_handle_t *phandle; 10125331Samw char option; 10135331Samw int pcnt = 0; 10145331Samw int ret; 10155331Samw int p; 10165331Samw 10175331Samw bzero(props, SMBADM_NPROP * sizeof (smbadm_prop_t)); 10185331Samw 10195331Samw while ((option = getopt(argc, argv, "p:")) != -1) { 10205331Samw switch (option) { 10215331Samw case 'p': 10225331Samw if (pcnt >= SMBADM_NPROP) { 10235331Samw (void) fprintf(stderr, 10245331Samw gettext("exceeded number of supported" 10255331Samw " properties\n")); 10265331Samw smbadm_usage(B_FALSE); 10275331Samw } 10285331Samw 10295772Sas200622 if (smbadm_prop_parse(optarg, &props[pcnt++]) != 0) 10305772Sas200622 smbadm_usage(B_FALSE); 10315331Samw break; 10325331Samw 10335331Samw default: 10345331Samw smbadm_usage(B_FALSE); 10355331Samw } 10365331Samw } 10375331Samw 10385331Samw if (pcnt == 0) { 10395331Samw (void) fprintf(stderr, 10405331Samw gettext("missing property=value argument\n")); 10415331Samw smbadm_usage(B_FALSE); 10425331Samw } 10435331Samw 10445331Samw gname = argv[optind]; 10455331Samw if (optind >= argc || gname == NULL || *gname == '\0') { 10465331Samw (void) fprintf(stderr, gettext("missing group name\n")); 10475331Samw smbadm_usage(B_FALSE); 10485331Samw } 10495331Samw 10505331Samw for (p = 0; p < pcnt; p++) { 10515331Samw phandle = smbadm_prop_gethandle(props[p].p_name); 10525331Samw if (phandle) { 10535331Samw if (phandle->p_setfn(gname, &props[p]) != 0) 10545331Samw ret = 1; 10555331Samw } 10565331Samw } 10575331Samw 10585331Samw return (ret); 10595331Samw } 10605331Samw 10615331Samw /* 10625331Samw * smbadm_group_getprop 10635331Samw * 10645331Samw * Get the group properties. 10655331Samw */ 10665331Samw static int 10675331Samw smbadm_group_getprop(int argc, char **argv) 10685331Samw { 10695331Samw char *gname = NULL; 10705331Samw smbadm_prop_t props[SMBADM_NPROP]; 10715331Samw smbadm_prop_handle_t *phandle; 10725331Samw char option; 10735331Samw int pcnt = 0; 10745331Samw int ret; 10755331Samw int p; 10765331Samw 10775331Samw bzero(props, SMBADM_NPROP * sizeof (smbadm_prop_t)); 10785331Samw 10795331Samw while ((option = getopt(argc, argv, "p:")) != -1) { 10805331Samw switch (option) { 10815331Samw case 'p': 10825331Samw if (pcnt >= SMBADM_NPROP) { 10835331Samw (void) fprintf(stderr, 10845331Samw gettext("exceeded number of supported" 10855331Samw " properties\n")); 10865331Samw smbadm_usage(B_FALSE); 10875331Samw } 10885331Samw 10895772Sas200622 if (smbadm_prop_parse(optarg, &props[pcnt++]) != 0) 10905772Sas200622 smbadm_usage(B_FALSE); 10915331Samw break; 10925331Samw 10935331Samw default: 10945331Samw smbadm_usage(B_FALSE); 10955331Samw } 10965331Samw } 10975331Samw 10985331Samw gname = argv[optind]; 10995331Samw if (optind >= argc || gname == NULL || *gname == '\0') { 11005331Samw (void) fprintf(stderr, gettext("missing group name\n")); 11015331Samw smbadm_usage(B_FALSE); 11025331Samw } 11035331Samw 11045331Samw if (pcnt == 0) { 11055331Samw /* 11065331Samw * If no property has be specified then get 11075331Samw * all the properties. 11085331Samw */ 11095331Samw pcnt = SMBADM_NPROP; 11105331Samw for (p = 0; p < pcnt; p++) 11115331Samw props[p].p_name = smbadm_ptable[p].p_name; 11125331Samw } 11135331Samw 11145331Samw for (p = 0; p < pcnt; p++) { 11155331Samw phandle = smbadm_prop_gethandle(props[p].p_name); 11165331Samw if (phandle) { 11175331Samw if (phandle->p_getfn(gname, &props[p]) != 0) 11185331Samw ret = 1; 11195331Samw } 11205331Samw } 11215331Samw 11225331Samw return (ret); 11235331Samw } 11245331Samw 11255331Samw /* 11265331Samw * smbadm_group_addmember 11275331Samw * 11285331Samw */ 11295331Samw static int 11305331Samw smbadm_group_addmember(int argc, char **argv) 11315331Samw { 1132*11337SWilliam.Krier@Sun.COM lsa_account_t acct; 11335331Samw char *gname = NULL; 11345331Samw char **mname; 11355331Samw char option; 11365772Sas200622 smb_gsid_t msid; 11375772Sas200622 int status; 11385331Samw int mcnt = 0; 11395331Samw int ret = 0; 11405331Samw int i; 11415331Samw 11425331Samw 11435331Samw mname = (char **)malloc(argc * sizeof (char *)); 11445331Samw if (mname == NULL) { 11458334SJose.Borrego@Sun.COM warn(gettext("failed to add group member")); 11465331Samw return (1); 11475331Samw } 11485331Samw bzero(mname, argc * sizeof (char *)); 11495331Samw 11505331Samw while ((option = getopt(argc, argv, "m:")) != -1) { 11515331Samw switch (option) { 11525331Samw case 'm': 11535331Samw mname[mcnt++] = optarg; 11545331Samw break; 11555331Samw 11565331Samw default: 11575331Samw free(mname); 11585331Samw smbadm_usage(B_FALSE); 11595331Samw } 11605331Samw } 11615331Samw 11625331Samw if (mcnt == 0) { 11635331Samw (void) fprintf(stderr, gettext("missing member name\n")); 11645331Samw free(mname); 11655331Samw smbadm_usage(B_FALSE); 11665331Samw } 11675331Samw 11685331Samw gname = argv[optind]; 11695331Samw if (optind >= argc || gname == NULL || *gname == 0) { 11705331Samw (void) fprintf(stderr, gettext("missing group name\n")); 11715331Samw free(mname); 11725331Samw smbadm_usage(B_FALSE); 11735331Samw } 11745331Samw 11755331Samw 11765331Samw for (i = 0; i < mcnt; i++) { 1177*11337SWilliam.Krier@Sun.COM ret = 0; 11785331Samw if (mname[i] == NULL) 11795331Samw continue; 11805331Samw 1181*11337SWilliam.Krier@Sun.COM ret = smb_lookup_name(mname[i], SidTypeUnknown, &acct); 1182*11337SWilliam.Krier@Sun.COM if ((ret != 0) || (acct.a_status != NT_STATUS_SUCCESS)) { 11835772Sas200622 (void) fprintf(stderr, 11848334SJose.Borrego@Sun.COM gettext("failed to add %s: unable to obtain SID\n"), 11855772Sas200622 mname[i]); 11865772Sas200622 continue; 11875772Sas200622 } 11885772Sas200622 1189*11337SWilliam.Krier@Sun.COM msid.gs_type = acct.a_sidtype; 1190*11337SWilliam.Krier@Sun.COM 1191*11337SWilliam.Krier@Sun.COM if ((msid.gs_sid = smb_sid_fromstr(acct.a_sid)) == NULL) { 1192*11337SWilliam.Krier@Sun.COM (void) fprintf(stderr, 1193*11337SWilliam.Krier@Sun.COM gettext("failed to add %s: no memory\n"), mname[i]); 1194*11337SWilliam.Krier@Sun.COM continue; 1195*11337SWilliam.Krier@Sun.COM } 1196*11337SWilliam.Krier@Sun.COM 11975772Sas200622 status = smb_lgrp_add_member(gname, msid.gs_sid, msid.gs_type); 1198*11337SWilliam.Krier@Sun.COM smb_sid_free(msid.gs_sid); 11995772Sas200622 if (status != SMB_LGRP_SUCCESS) { 12005331Samw (void) fprintf(stderr, 12015331Samw gettext("failed to add %s (%s)\n"), 12025772Sas200622 mname[i], smb_lgrp_strerror(status)); 12035331Samw ret = 1; 12045772Sas200622 } else { 12055772Sas200622 (void) printf(gettext("'%s' is now a member of '%s'\n"), 12065772Sas200622 mname[i], gname); 12075331Samw } 12085331Samw } 12095331Samw 12105331Samw free(mname); 12115331Samw return (ret); 12125331Samw } 12135331Samw 12145331Samw /* 12155331Samw * smbadm_group_delmember 12165331Samw */ 12175331Samw static int 12185331Samw smbadm_group_delmember(int argc, char **argv) 12195331Samw { 1220*11337SWilliam.Krier@Sun.COM lsa_account_t acct; 12215331Samw char *gname = NULL; 12225331Samw char **mname; 12235331Samw char option; 12245772Sas200622 smb_gsid_t msid; 12255772Sas200622 int status; 12265331Samw int mcnt = 0; 12275331Samw int ret = 0; 12285331Samw int i; 12295331Samw 12305331Samw mname = (char **)malloc(argc * sizeof (char *)); 12315331Samw if (mname == NULL) { 12328334SJose.Borrego@Sun.COM warn(gettext("failed to delete group member")); 12335331Samw return (1); 12345331Samw } 12355331Samw bzero(mname, argc * sizeof (char *)); 12365331Samw 12375331Samw while ((option = getopt(argc, argv, "m:")) != -1) { 12385331Samw switch (option) { 12395331Samw case 'm': 12405331Samw mname[mcnt++] = optarg; 12415331Samw break; 12425331Samw 12435331Samw default: 12445331Samw free(mname); 12455331Samw smbadm_usage(B_FALSE); 12465331Samw } 12475331Samw } 12485331Samw 12495331Samw if (mcnt == 0) { 12505331Samw (void) fprintf(stderr, gettext("missing member name\n")); 12515331Samw free(mname); 12525331Samw smbadm_usage(B_FALSE); 12535331Samw } 12545331Samw 12555331Samw gname = argv[optind]; 12565331Samw if (optind >= argc || gname == NULL || *gname == 0) { 12575331Samw (void) fprintf(stderr, gettext("missing group name\n")); 12585331Samw free(mname); 12595331Samw smbadm_usage(B_FALSE); 12605331Samw } 12615331Samw 12625331Samw 12635331Samw for (i = 0; i < mcnt; i++) { 1264*11337SWilliam.Krier@Sun.COM ret = 0; 12655331Samw if (mname[i] == NULL) 12665331Samw continue; 12675331Samw 1268*11337SWilliam.Krier@Sun.COM ret = smb_lookup_name(mname[i], SidTypeUnknown, &acct); 1269*11337SWilliam.Krier@Sun.COM if ((ret != 0) || (acct.a_status != NT_STATUS_SUCCESS)) { 12705772Sas200622 (void) fprintf(stderr, 12718334SJose.Borrego@Sun.COM gettext("failed to remove %s: " 12728334SJose.Borrego@Sun.COM "unable to obtain SID\n"), 12735772Sas200622 mname[i]); 12745772Sas200622 continue; 12755772Sas200622 } 12765772Sas200622 1277*11337SWilliam.Krier@Sun.COM msid.gs_type = acct.a_sidtype; 1278*11337SWilliam.Krier@Sun.COM 1279*11337SWilliam.Krier@Sun.COM if ((msid.gs_sid = smb_sid_fromstr(acct.a_sid)) == NULL) { 1280*11337SWilliam.Krier@Sun.COM (void) fprintf(stderr, 1281*11337SWilliam.Krier@Sun.COM gettext("failed to remove %s: no memory\n"), 1282*11337SWilliam.Krier@Sun.COM mname[i]); 1283*11337SWilliam.Krier@Sun.COM continue; 1284*11337SWilliam.Krier@Sun.COM } 1285*11337SWilliam.Krier@Sun.COM 12865772Sas200622 status = smb_lgrp_del_member(gname, msid.gs_sid, msid.gs_type); 1287*11337SWilliam.Krier@Sun.COM smb_sid_free(msid.gs_sid); 12885772Sas200622 if (status != SMB_LGRP_SUCCESS) { 12895331Samw (void) fprintf(stderr, 12905331Samw gettext("failed to remove %s (%s)\n"), 12915772Sas200622 mname[i], smb_lgrp_strerror(status)); 12925331Samw ret = 1; 12935331Samw } else { 12945331Samw (void) printf( 12955772Sas200622 gettext("'%s' has been removed from %s\n"), 12965331Samw mname[i], gname); 12975331Samw } 12985331Samw } 12995331Samw 13005331Samw return (ret); 13015331Samw } 13025331Samw 13035331Samw static int 13045331Samw smbadm_user_disable(int argc, char **argv) 13055331Samw { 13065331Samw int error; 13075331Samw char *user = NULL; 13085331Samw 13095331Samw user = argv[optind]; 13105331Samw if (optind >= argc || user == NULL || *user == '\0') { 13115331Samw (void) fprintf(stderr, gettext("missing user name\n")); 13125331Samw smbadm_usage(B_FALSE); 13135331Samw } 13145331Samw 13155331Samw error = smb_pwd_setcntl(user, SMB_PWC_DISABLE); 13165331Samw if (error == SMB_PWE_SUCCESS) 13175331Samw (void) printf(gettext("%s is disabled.\n"), user); 13185331Samw else 13195331Samw (void) fprintf(stderr, "%s\n", smbadm_pwd_strerror(error)); 13205331Samw 13215331Samw return (error); 13225331Samw } 13235331Samw 13245331Samw static int 13255331Samw smbadm_user_enable(int argc, char **argv) 13265331Samw { 13275331Samw int error; 13285331Samw char *user = NULL; 13295331Samw 13305331Samw user = argv[optind]; 13315331Samw if (optind >= argc || user == NULL || *user == '\0') { 13325331Samw (void) fprintf(stderr, gettext("missing user name\n")); 13335331Samw smbadm_usage(B_FALSE); 13345331Samw } 13355331Samw 13365331Samw error = smb_pwd_setcntl(user, SMB_PWC_ENABLE); 13375331Samw if (error == SMB_PWE_SUCCESS) 13385331Samw (void) printf(gettext("%s is enabled.\n"), user); 13395331Samw else 13405331Samw (void) fprintf(stderr, "%s\n", smbadm_pwd_strerror(error)); 13415331Samw 13425331Samw return (error); 13435331Samw } 13445331Samw 13455331Samw 13465331Samw int 13475331Samw main(int argc, char **argv) 13485331Samw { 13495772Sas200622 int ret; 13505331Samw int i; 13515331Samw 13525331Samw (void) malloc(0); /* satisfy libumem dependency */ 13535331Samw 13545331Samw progname = basename(argv[0]); 13555331Samw 13565331Samw if (getzoneid() != GLOBAL_ZONEID) { 13575331Samw (void) fprintf(stderr, 13585331Samw gettext("cannot execute in non-global zone\n")); 13595331Samw return (0); 13605331Samw } 13615331Samw 13625331Samw if (is_system_labeled()) { 13635331Samw (void) fprintf(stderr, 13645331Samw gettext("Trusted Extensions not supported\n")); 13655331Samw return (0); 13665331Samw } 13675331Samw 13685331Samw if (argc < 2) { 13695331Samw (void) fprintf(stderr, gettext("missing command\n")); 13705331Samw smbadm_usage(B_FALSE); 13715331Samw } 13725331Samw 13735331Samw /* 13745331Samw * Special case "cmd --help/-?" 13755331Samw */ 13765331Samw if (strcmp(argv[1], "-?") == 0 || 13775331Samw strcmp(argv[1], "--help") == 0 || 13785331Samw strcmp(argv[1], "-h") == 0) 13795331Samw smbadm_usage(B_TRUE); 13805331Samw 13815331Samw for (i = 0; i < SMBADM_NCMD; ++i) { 13825331Samw curcmd = &smbadm_cmdtable[i]; 13835331Samw if (strcasecmp(argv[1], curcmd->name) == 0) { 13845331Samw if (argc > 2) { 13855331Samw /* cmd subcmd --help/-? */ 13865331Samw if (strcmp(argv[2], "-?") == 0 || 13875331Samw strcmp(argv[2], "--help") == 0 || 13885331Samw strcmp(argv[2], "-h") == 0) 13895331Samw smbadm_usage(B_TRUE); 13905331Samw } 13915331Samw 13927052Samw if ((ret = smbadm_init()) != 0) 13936139Sjb150015 return (ret); 13945772Sas200622 13955772Sas200622 ret = curcmd->func(argc - 1, &argv[1]); 13966139Sjb150015 13977052Samw smbadm_fini(); 13985772Sas200622 return (ret); 13995331Samw } 14005331Samw } 14015331Samw 14025331Samw curcmd = NULL; 14035331Samw (void) fprintf(stderr, gettext("unknown subcommand (%s)\n"), argv[1]); 14045331Samw smbadm_usage(B_FALSE); 14055331Samw return (2); 14065331Samw } 14075331Samw 14086139Sjb150015 static int 14097052Samw smbadm_init(void) 14106139Sjb150015 { 14116139Sjb150015 int rc; 14126139Sjb150015 14137052Samw switch (curcmd->flags & SMBADM_CMDF_TYPEMASK) { 14147052Samw case SMBADM_CMDF_GROUP: 14156139Sjb150015 if (smb_idmap_start() != 0) { 14166139Sjb150015 (void) fprintf(stderr, 14176139Sjb150015 gettext("failed to contact idmap service\n")); 14186139Sjb150015 return (1); 14196139Sjb150015 } 14206139Sjb150015 14216139Sjb150015 if ((rc = smb_lgrp_start()) != SMB_LGRP_SUCCESS) { 14226139Sjb150015 (void) fprintf(stderr, 14236139Sjb150015 gettext("failed to initialize (%s)\n"), 14246139Sjb150015 smb_lgrp_strerror(rc)); 14256139Sjb150015 smb_idmap_stop(); 14266139Sjb150015 return (1); 14276139Sjb150015 } 14287052Samw break; 14297052Samw 14307052Samw case SMBADM_CMDF_USER: 14317052Samw smb_pwd_init(B_FALSE); 14327052Samw break; 14337052Samw 14347052Samw default: 14357052Samw break; 14366139Sjb150015 } 14376139Sjb150015 14386139Sjb150015 return (0); 14396139Sjb150015 } 14406139Sjb150015 14416139Sjb150015 static void 14427052Samw smbadm_fini(void) 14436139Sjb150015 { 14447052Samw switch (curcmd->flags & SMBADM_CMDF_TYPEMASK) { 14457052Samw case SMBADM_CMDF_GROUP: 14466139Sjb150015 smb_lgrp_stop(); 14476139Sjb150015 smb_idmap_stop(); 14487052Samw break; 14497052Samw 14507052Samw case SMBADM_CMDF_USER: 14517052Samw smb_pwd_fini(); 14527052Samw break; 14537052Samw 14547052Samw default: 14557052Samw break; 14566139Sjb150015 } 14576139Sjb150015 } 14586139Sjb150015 14595331Samw static boolean_t 14605331Samw smbadm_prop_validate(smbadm_prop_t *prop, boolean_t chkval) 14615331Samw { 14625331Samw smbadm_prop_handle_t *pinfo; 14635331Samw int i; 14645331Samw 14655331Samw for (i = 0; i < SMBADM_NPROP; i++) { 14665331Samw pinfo = &smbadm_ptable[i]; 14675331Samw if (strcmp(pinfo->p_name, prop->p_name) == 0) { 14685331Samw if (pinfo->p_chkfn && chkval) 14695331Samw return (pinfo->p_chkfn(prop)); 14705331Samw 14715331Samw return (B_TRUE); 14725331Samw } 14735331Samw } 14745331Samw 14758334SJose.Borrego@Sun.COM (void) fprintf(stderr, gettext("unrecognized property '%s'\n"), 14768334SJose.Borrego@Sun.COM prop->p_name); 14775331Samw 14785331Samw return (B_FALSE); 14795331Samw } 14805331Samw 14815331Samw static int 14825331Samw smbadm_prop_parse(char *arg, smbadm_prop_t *prop) 14835331Samw { 14845331Samw boolean_t parse_value; 14855331Samw char *equal; 14865331Samw 14875331Samw if (arg == NULL) 14885331Samw return (2); 14895331Samw 14905331Samw prop->p_name = prop->p_value = NULL; 14915331Samw 14925331Samw if (strcmp(curcmd->name, "set") == 0) 14935331Samw parse_value = B_TRUE; 14945331Samw else 14955331Samw parse_value = B_FALSE; 14965331Samw 14975331Samw prop->p_name = arg; 14985331Samw 14995331Samw if (parse_value) { 15005331Samw equal = strchr(arg, '='); 15015331Samw if (equal == NULL) 15025331Samw return (2); 15035331Samw 15045331Samw *equal++ = '\0'; 15055331Samw prop->p_value = equal; 15065331Samw } 15075331Samw 15085331Samw if (smbadm_prop_validate(prop, parse_value) == B_FALSE) 15095331Samw return (2); 15105331Samw 15115331Samw return (0); 15125331Samw } 15135331Samw 15145331Samw static smbadm_prop_handle_t * 15155331Samw smbadm_prop_gethandle(char *pname) 15165331Samw { 15175331Samw int i; 15185331Samw 15195331Samw for (i = 0; i < SMBADM_NPROP; i++) 15205331Samw if (strcmp(pname, smbadm_ptable[i].p_name) == 0) 15215331Samw return (&smbadm_ptable[i]); 15225331Samw 15235331Samw return (NULL); 15245331Samw } 15255331Samw 15265331Samw static int 15275331Samw smbadm_setprop_desc(char *gname, smbadm_prop_t *prop) 15285331Samw { 15295772Sas200622 int status; 15305331Samw 15315772Sas200622 status = smb_lgrp_setcmnt(gname, prop->p_value); 15325772Sas200622 if (status != SMB_LGRP_SUCCESS) { 15335331Samw (void) fprintf(stderr, 15345331Samw gettext("failed to modify the group description (%s)\n"), 15355772Sas200622 smb_lgrp_strerror(status)); 15365331Samw return (1); 15375331Samw } 15385331Samw 15398334SJose.Borrego@Sun.COM (void) printf(gettext("%s: description modified\n"), gname); 15405331Samw return (0); 15415331Samw } 15425331Samw 15435331Samw static int 15445331Samw smbadm_getprop_desc(char *gname, smbadm_prop_t *prop) 15455331Samw { 15465772Sas200622 char *cmnt = NULL; 15475772Sas200622 int status; 15485331Samw 15495772Sas200622 status = smb_lgrp_getcmnt(gname, &cmnt); 15505772Sas200622 if (status != SMB_LGRP_SUCCESS) { 15515331Samw (void) fprintf(stderr, 15525772Sas200622 gettext("failed to get the group description (%s)\n"), 15535772Sas200622 smb_lgrp_strerror(status)); 15545331Samw return (1); 15555331Samw } 15565331Samw 15575772Sas200622 (void) printf(gettext("\t%s: %s\n"), prop->p_name, cmnt); 15585772Sas200622 free(cmnt); 15595331Samw return (0); 15605331Samw } 15615331Samw 15625331Samw static int 15635772Sas200622 smbadm_group_setpriv(char *gname, uint8_t priv_id, smbadm_prop_t *prop) 15645331Samw { 15655772Sas200622 boolean_t enable; 15665772Sas200622 int status; 15675331Samw int ret; 15685331Samw 15695331Samw if (strcasecmp(prop->p_value, "on") == 0) { 15705331Samw (void) printf(gettext("Enabling %s privilege "), prop->p_name); 15715772Sas200622 enable = B_TRUE; 15725331Samw } else { 15735331Samw (void) printf(gettext("Disabling %s privilege "), prop->p_name); 15745772Sas200622 enable = B_FALSE; 15755331Samw } 15765331Samw 15775772Sas200622 status = smb_lgrp_setpriv(gname, priv_id, enable); 15785772Sas200622 if (status == SMB_LGRP_SUCCESS) { 15795331Samw (void) printf(gettext("succeeded\n")); 15805331Samw ret = 0; 15815331Samw } else { 15825772Sas200622 (void) printf(gettext("failed: %s\n"), 15835772Sas200622 smb_lgrp_strerror(status)); 15845331Samw ret = 1; 15855331Samw } 15865331Samw 15875331Samw return (ret); 15885331Samw } 15895331Samw 15905331Samw static int 15915772Sas200622 smbadm_group_getpriv(char *gname, uint8_t priv_id, smbadm_prop_t *prop) 15925331Samw { 15935772Sas200622 boolean_t enable; 15945772Sas200622 int status; 15955331Samw 15965772Sas200622 status = smb_lgrp_getpriv(gname, priv_id, &enable); 15975772Sas200622 if (status != SMB_LGRP_SUCCESS) { 15985331Samw (void) fprintf(stderr, gettext("failed to get %s (%s)\n"), 15995772Sas200622 prop->p_name, smb_lgrp_strerror(status)); 16005331Samw return (1); 16015331Samw } 16025331Samw 16035772Sas200622 (void) printf(gettext("\t%s: %s\n"), prop->p_name, 16045772Sas200622 (enable) ? "On" : "Off"); 16055331Samw 16065331Samw return (0); 16075331Samw } 16085331Samw 16095331Samw static int 16105331Samw smbadm_setprop_tkowner(char *gname, smbadm_prop_t *prop) 16115331Samw { 16125331Samw return (smbadm_group_setpriv(gname, SE_TAKE_OWNERSHIP_LUID, prop)); 16135331Samw } 16145331Samw 16155331Samw static int 16165331Samw smbadm_getprop_tkowner(char *gname, smbadm_prop_t *prop) 16175331Samw { 16185331Samw return (smbadm_group_getpriv(gname, SE_TAKE_OWNERSHIP_LUID, prop)); 16195331Samw } 16205331Samw 16215331Samw static int 16225331Samw smbadm_setprop_backup(char *gname, smbadm_prop_t *prop) 16235331Samw { 16245331Samw return (smbadm_group_setpriv(gname, SE_BACKUP_LUID, prop)); 16255331Samw } 16265331Samw 16275331Samw static int 16285331Samw smbadm_getprop_backup(char *gname, smbadm_prop_t *prop) 16295331Samw { 16305331Samw return (smbadm_group_getpriv(gname, SE_BACKUP_LUID, prop)); 16315331Samw } 16325331Samw 16335331Samw static int 16345331Samw smbadm_setprop_restore(char *gname, smbadm_prop_t *prop) 16355331Samw { 16365331Samw return (smbadm_group_setpriv(gname, SE_RESTORE_LUID, prop)); 16375331Samw } 16385331Samw 16395331Samw static int 16405331Samw smbadm_getprop_restore(char *gname, smbadm_prop_t *prop) 16415331Samw { 16425331Samw return (smbadm_group_getpriv(gname, SE_RESTORE_LUID, prop)); 16435331Samw } 16445331Samw 16455331Samw static boolean_t 16465331Samw smbadm_chkprop_priv(smbadm_prop_t *prop) 16475331Samw { 16485331Samw if (prop->p_value == NULL || *prop->p_value == '\0') { 16495331Samw (void) fprintf(stderr, 16505331Samw gettext("missing value for '%s'\n"), prop->p_name); 16515331Samw return (B_FALSE); 16525331Samw } 16535331Samw 16545331Samw if (strcasecmp(prop->p_value, "on") == 0) 16555331Samw return (B_TRUE); 16565331Samw 16575331Samw if (strcasecmp(prop->p_value, "off") == 0) 16585331Samw return (B_TRUE); 16595331Samw 16605331Samw (void) fprintf(stderr, 16615331Samw gettext("%s: unrecognized value for '%s' property\n"), 16625331Samw prop->p_value, prop->p_name); 16635331Samw 16645331Samw return (B_FALSE); 16655331Samw } 16665331Samw 16675331Samw static const char * 16685331Samw smbadm_pwd_strerror(int error) 16695331Samw { 16705331Samw switch (error) { 16715331Samw case SMB_PWE_SUCCESS: 16725331Samw return (gettext("Success.")); 16735331Samw 16745331Samw case SMB_PWE_USER_UNKNOWN: 16755331Samw return (gettext("User does not exist.")); 16765331Samw 16775331Samw case SMB_PWE_USER_DISABLE: 16788334SJose.Borrego@Sun.COM return (gettext("User is disabled.")); 16795331Samw 16805331Samw case SMB_PWE_CLOSE_FAILED: 16815331Samw case SMB_PWE_OPEN_FAILED: 16825331Samw case SMB_PWE_WRITE_FAILED: 16835331Samw case SMB_PWE_UPDATE_FAILED: 16845331Samw return (gettext("Unexpected failure. " 16855331Samw "SMB password database unchanged.")); 16865331Samw 16875331Samw case SMB_PWE_STAT_FAILED: 16885331Samw return (gettext("stat of SMB password file failed.")); 16895331Samw 16905331Samw case SMB_PWE_BUSY: 16915331Samw return (gettext("SMB password database busy. " 16925331Samw "Try again later.")); 16935331Samw 16945331Samw case SMB_PWE_DENIED: 16955331Samw return (gettext("Operation not permitted.")); 16965331Samw 16975331Samw case SMB_PWE_SYSTEM_ERROR: 16985331Samw return (gettext("System error.")); 16997052Samw 17007052Samw default: 17017052Samw break; 17025331Samw } 17035331Samw 17045331Samw return (gettext("Unknown error code.")); 17055331Samw } 17065331Samw 17075331Samw /* 17085331Samw * Enable libumem debugging by default on DEBUG builds. 17095331Samw */ 17105331Samw #ifdef DEBUG 17115331Samw const char * 17125331Samw _umem_debug_init(void) 17135331Samw { 17145331Samw return ("default,verbose"); /* $UMEM_DEBUG setting */ 17155331Samw } 17165331Samw 17175331Samw const char * 17185331Samw _umem_logging_init(void) 17195331Samw { 17205331Samw return ("fail,contents"); /* $UMEM_LOGGING setting */ 17215331Samw } 17225331Samw #endif 1723