diff options
Diffstat (limited to 'source3/utils')
-rw-r--r-- | source3/utils/smbpasswd.c | 359 |
1 files changed, 181 insertions, 178 deletions
diff --git a/source3/utils/smbpasswd.c b/source3/utils/smbpasswd.c index a718ed5110..de7e66a084 100644 --- a/source3/utils/smbpasswd.c +++ b/source3/utils/smbpasswd.c @@ -29,25 +29,12 @@ 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; -#ifdef WITH_LDAP_SAM -static fstring ldap_secret; -#endif - -/********************************************************* - Print command usage on stderr and die. -**********************************************************/ +/** + * Print command usage on stderr and die. + **/ static void usage(void) { printf("When run by root:\n"); @@ -56,14 +43,13 @@ 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"); printf(" -r MACHINE remote machine\n"); printf("extra options when run by root or in local mode:\n"); - printf(" -L local mode\n"); + printf(" -L local mode (must be first option)\n"); printf(" -R ORDER name resolve order\n"); printf(" -a add user\n"); printf(" -x delete user\n"); @@ -84,144 +70,6 @@ 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; - 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. @@ -343,15 +191,108 @@ static BOOL store_ldap_admin_pw (char* pw) } #endif - /************************************************************* Handle password changing for root. *************************************************************/ -static int process_root(void) +static int process_root(int argc, char *argv[]) { struct passwd *pwd; - int result = 0; + 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; #ifdef WITH_LDAP_SAM if (local_flags & LOCAL_SET_LDAP_ADMIN_PW) @@ -363,7 +304,6 @@ static int process_root(void) goto done; } #endif - /* * Ensure both add/delete user are not set * Ensure add/delete user and either remote machine or join domain are @@ -381,6 +321,30 @@ static int process_root(void) 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); } @@ -502,19 +466,56 @@ static int process_root(void) } -/************************************************************* - Handle password changing for non-root. -*************************************************************/ - -static int process_nonroot(void) +/** + handle password changing for non-root +**/ +static int process_nonroot(int argc, char *argv[]) { struct passwd *pwd = NULL; - int result = 0; + 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; + + 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 (!user_name[0]) { + if(argc > 1) { + usage(); + } + + if (argc == 1) { + new_passwd = argv[0]; + } + + if (!user_name) { pwd = sys_getpwuid(getuid()); if (pwd) { - fstrcpy(user_name,pwd->pw_name); + user_name = smb_xstrdup(pwd->pw_name); } else { fprintf(stderr, "smbpasswd: you don't exist - go away\n"); exit(1); @@ -568,20 +569,15 @@ static int process_nonroot(void) **********************************************************/ 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(configfile,True,False,False)) { + if (!lp_load(dyn_CONFIGFILE,True,False,False)) { fprintf(stderr, "Can't load %s - run testparm to debug it\n", dyn_CONFIGFILE); exit(1); @@ -606,10 +602,17 @@ int main(int argc, char **argv) exit(1); } - if (local_mode || amroot) { + /* 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) { secrets_init(); - return process_root(); + return process_root(argc, argv); } - return process_nonroot(); + return process_nonroot(argc, argv); } |