diff --git a/source/utils/smbpasswd.c b/source/utils/smbpasswd.c index de7e66a0842..cd046dfb1bf 100644 --- a/source/utils/smbpasswd.c +++ b/source/utils/smbpasswd.c @@ -29,12 +29,25 @@ extern BOOL AllowDebugChange; extern char *optarg; extern int optind; -/** forced running in root-mode **/ +/* forced running in root-mode */ static BOOL local_mode; +static BOOL got_pass = False, got_username = False; +static int local_flags = 0; +static BOOL stdin_passwd_get = False; +static fstring user_name, user_password; +static char *new_domain = NULL; +static char *new_passwd = NULL; +static char *old_passwd = NULL; +static char *remote_machine = NULL; +static pstring configfile; -/** - * Print command usage on stderr and die. - **/ +#ifdef WITH_LDAP_SAM +static fstring ldap_secret; +#endif + +/********************************************************* + Print command usage on stderr and die. +**********************************************************/ static void usage(void) { printf("When run by root:\n"); @@ -43,6 +56,7 @@ static void usage(void) printf(" smbpasswd [options] [password]\n\n"); printf("options:\n"); + printf(" -c smb.conf file Use the given path to the smb.conf file\n"); printf(" -s use stdin for password prompt\n"); printf(" -D LEVEL debug level\n"); printf(" -U USER remote username\n"); @@ -70,6 +84,145 @@ static void set_line_buffering(FILE *f) setvbuf(f, NULL, _IOLBF, 0); } +/******************************************************************* + Process command line options + ******************************************************************/ +static void process_options(int argc, char **argv, BOOL amroot) +{ + int ch; + + if (amroot) + local_flags = LOCAL_SET_PASSWORD; + + ZERO_STRUCT(user_name); + ZERO_STRUCT(user_password); + + user_name[0] = '\0'; + + while ((ch = getopt(argc, argv, "c:axdehmnj:r:sw:R:D:U:L")) != EOF) { + switch(ch) { + case 'L': + local_mode = amroot = True; + local_flags = LOCAL_SET_PASSWORD; + break; + case 'c': + pstrcpy(configfile,optarg); + break; + case 'a': + if (!amroot) goto bad_args; + local_flags |= LOCAL_ADD_USER; + break; + case 'x': + if (!amroot) goto bad_args; + local_flags |= LOCAL_DELETE_USER; + local_flags &= ~LOCAL_SET_PASSWORD; + break; + case 'd': + if (!amroot) goto bad_args; + local_flags |= LOCAL_DISABLE_USER; + local_flags &= ~LOCAL_SET_PASSWORD; + break; + case 'e': + if (!amroot) goto bad_args; + local_flags |= LOCAL_ENABLE_USER; + local_flags &= ~LOCAL_SET_PASSWORD; + break; + case 'm': + if (!amroot) goto bad_args; + local_flags |= LOCAL_TRUST_ACCOUNT; + break; + case 'i': + if (!amroot) goto bad_args; + local_flags |= LOCAL_INTERDOM_ACCOUNT; + break; + case 'j': + if (!amroot) goto bad_args; + d_printf("See 'net rpc join' for this functionality\n"); + exit(1); + break; + case 'n': + if (!amroot) goto bad_args; + local_flags |= LOCAL_SET_NO_PASSWORD; + new_passwd = smb_xstrdup("NO PASSWORD"); + break; + case 'r': + remote_machine = optarg; + break; + case 's': + set_line_buffering(stdin); + set_line_buffering(stdout); + set_line_buffering(stderr); + stdin_passwd_get = True; + break; + case 'w': + if (!amroot) goto bad_args; +#ifdef WITH_LDAP_SAM + local_flags |= LOCAL_SET_LDAP_ADMIN_PW; + fstrcpy(ldap_secret, optarg); + break; +#else + printf("-w not available unless configured --with-ldap\n"); + goto bad_args; +#endif + case 'R': + if (!amroot) goto bad_args; + lp_set_name_resolve_order(optarg); + break; + case 'D': + DEBUGLEVEL = atoi(optarg); + break; + case 'U': { + char *lp; + + got_username = True; + fstrcpy(user_name, optarg); + + if ((lp = strchr(user_name, '%'))) { + *lp = 0; + fstrcpy(user_password, lp + 1); + got_pass = True; + memset(strchr_m(optarg, '%') + 1, 'X', + strlen(user_password)); + } + + break; + } + case 'h': + default: +bad_args: + usage(); + } + } + + argc -= optind; + argv += optind; + + switch(argc) { + case 0: + if (!got_username) + fstrcpy(user_name, ""); + break; + case 1: + if (!amroot) { + new_passwd = argv[0]; + break; + } + if (got_username) + usage(); + fstrcpy(user_name, argv[0]); + break; + case 2: + if (!amroot || got_username || got_pass) + usage(); + fstrcpy(user_name, argv[0]); + new_passwd = smb_xstrdup(argv[1]); + break; + default: + usage(); + } + +} + /************************************************************* Utility function to prompt for passwords from stdin. Each password entered must end with a newline. @@ -191,108 +344,15 @@ static BOOL store_ldap_admin_pw (char* pw) } #endif + /************************************************************* Handle password changing for root. *************************************************************/ -static int process_root(int argc, char *argv[]) +static int process_root(void) { struct passwd *pwd; - int result = 0, ch; - BOOL got_pass = False, got_username = False; - int local_flags = LOCAL_SET_PASSWORD; - BOOL stdin_passwd_get = False; - fstring user_name, user_password; - char *new_passwd = NULL; - char *old_passwd = NULL; - char *remote_machine = NULL; -#ifdef WITH_LDAP_SAM - fstring ldap_secret; -#endif - - ZERO_STRUCT(user_name); - ZERO_STRUCT(user_password); - - user_name[0] = '\0'; - - while ((ch = getopt(argc, argv, "axdehmnijr:sw:R:D:U:L")) != EOF) { - switch(ch) { - case 'L': - local_mode = True; - break; - case 'a': - local_flags |= LOCAL_ADD_USER; - break; - case 'x': - local_flags |= LOCAL_DELETE_USER; - local_flags &= ~LOCAL_SET_PASSWORD; - break; - case 'd': - local_flags |= LOCAL_DISABLE_USER; - local_flags &= ~LOCAL_SET_PASSWORD; - break; - case 'e': - local_flags |= LOCAL_ENABLE_USER; - local_flags &= ~LOCAL_SET_PASSWORD; - break; - case 'm': - local_flags |= LOCAL_TRUST_ACCOUNT; - break; - case 'i': - local_flags |= LOCAL_INTERDOM_ACCOUNT; - break; - case 'j': - d_printf("See 'net rpc join' for this functionality\n"); - exit(1); - break; - case 'r': - remote_machine = optarg; - break; - case 's': - set_line_buffering(stdin); - set_line_buffering(stdout); - set_line_buffering(stderr); - stdin_passwd_get = True; - break; - case 'w': -#ifdef WITH_LDAP_SAM - local_flags |= LOCAL_SET_LDAP_ADMIN_PW; - fstrcpy(ldap_secret, optarg); - break; -#else - printf("-w not available unless configured --with-ldap\n"); - goto done; -#endif - case 'R': - lp_set_name_resolve_order(optarg); - break; - case 'D': - DEBUGLEVEL = atoi(optarg); - break; - case 'U': { - char *lp; - - got_username = True; - fstrcpy(user_name, optarg); - - if ((lp = strchr_m(user_name, '%'))) { - *lp = 0; - fstrcpy(user_password, lp + 1); - got_pass = True; - memset(strchr_m(optarg, '%') + 1, 'X', - strlen(user_password)); - } - - break; - } - case 'h': - default: - usage(); - } - } - - argc -= optind; - argv += optind; + int result = 0; #ifdef WITH_LDAP_SAM if (local_flags & LOCAL_SET_LDAP_ADMIN_PW) @@ -304,6 +364,7 @@ static int process_root(int argc, char *argv[]) goto done; } #endif + /* * Ensure both add/delete user are not set * Ensure add/delete user and either remote machine or join domain are @@ -321,30 +382,6 @@ static int process_root(int argc, char *argv[]) load_interfaces(); } - /* - * Deal with root - can add a user, but only locally. - */ - - switch(argc) { - case 0: - if (!got_username) - fstrcpy(user_name, ""); - break; - case 1: - if (got_username) - usage(); - fstrcpy(user_name, argv[0]); - break; - case 2: - if (got_username || got_pass) - usage(); - fstrcpy(user_name, argv[0]); - new_passwd = smb_xstrdup(argv[1]); - break; - default: - usage(); - } - if (!user_name[0] && (pwd = sys_getpwuid(geteuid()))) { fstrcpy(user_name, pwd->pw_name); } @@ -466,56 +503,19 @@ static int process_root(int argc, char *argv[]) } -/** - handle password changing for non-root -**/ -static int process_nonroot(int argc, char *argv[]) +/************************************************************* + Handle password changing for non-root. +*************************************************************/ + +static int process_nonroot(void) { struct passwd *pwd = NULL; - int result = 0, ch; - BOOL stdin_passwd_get = False; - char *old_passwd = NULL; - char *remote_machine = NULL; - char *user_name = NULL; - char *new_passwd = NULL; + int result = 0; - while ((ch = getopt(argc, argv, "hD:r:sU:")) != EOF) { - switch(ch) { - case 'D': - DEBUGLEVEL = atoi(optarg); - break; - case 'r': - remote_machine = optarg; - break; - case 's': - set_line_buffering(stdin); - set_line_buffering(stdout); - set_line_buffering(stderr); - stdin_passwd_get = True; - break; - case 'U': - user_name = optarg; - break; - default: - usage(); - } - } - - argc -= optind; - argv += optind; - - if(argc > 1) { - usage(); - } - - if (argc == 1) { - new_passwd = argv[0]; - } - - if (!user_name) { + if (!user_name[0]) { pwd = sys_getpwuid(getuid()); if (pwd) { - user_name = smb_xstrdup(pwd->pw_name); + fstrcpy(user_name,pwd->pw_name); } else { fprintf(stderr, "smbpasswd: you don't exist - go away\n"); exit(1); @@ -569,15 +569,20 @@ static int process_nonroot(int argc, char *argv[]) **********************************************************/ int main(int argc, char **argv) { + BOOL amroot = getuid() == 0; + + pstrcpy(configfile, dyn_CONFIGFILE); AllowDebugChange = False; #if defined(HAVE_SET_AUTH_PARAMETERS) set_auth_parameters(argc, argv); #endif /* HAVE_SET_AUTH_PARAMETERS */ + process_options(argc, argv, amroot); + setup_logging("smbpasswd", True); - if (!lp_load(dyn_CONFIGFILE,True,False,False)) { + if (!lp_load(configfile,True,False,False)) { fprintf(stderr, "Can't load %s - run testparm to debug it\n", dyn_CONFIGFILE); exit(1); @@ -602,17 +607,10 @@ int main(int argc, char **argv) exit(1); } - /* pre-check for local mode option as first option. We can't - do this via normal getopt as getopt can't be called - twice. */ - if (argc > 1 && strcmp(argv[1], "-L") == 0) { - local_mode = True; - } - - if (local_mode || getuid() == 0) { + if (local_mode || amroot) { secrets_init(); - return process_root(argc, argv); + return process_root(); } - return process_nonroot(argc, argv); + return process_nonroot(); }