diff options
Diffstat (limited to 'source/utils/smbpasswd.c')
-rw-r--r-- | source/utils/smbpasswd.c | 459 |
1 files changed, 219 insertions, 240 deletions
diff --git a/source/utils/smbpasswd.c b/source/utils/smbpasswd.c index 0e40d127178..24185114f13 100644 --- a/source/utils/smbpasswd.c +++ b/source/utils/smbpasswd.c @@ -33,21 +33,6 @@ extern int optind; /* forced running in root-mode */ static BOOL local_mode; -static BOOL joining_domain = False, 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 servicesf = CONFIGFILE; - -#ifdef WITH_LDAP_SAM -static fstring ldap_secret; -#endif - - /********************************************************* A strdup with exit @@ -69,170 +54,32 @@ static char *strdup_x(const char *s) **********************************************************/ static void usage(void) { - printf("When run by root:\n"); - printf(" smbpasswd [options] [username] [password]\n"); - printf("otherwise:\n"); - printf(" smbpasswd [options] [password]\n\n"); - + if (getuid() == 0) { + printf("smbpasswd [options] [username] [password]\n"); + } else { + printf("smbpasswd [options] [password]\n"); + } printf("options:\n"); - printf(" -L local mode (must be first option)\n"); - printf(" -h print this usage message\n"); printf(" -s use stdin for password prompt\n"); - printf(" -c smb.conf file Use the given path to the smb.conf file\n"); printf(" -D LEVEL debug level\n"); - printf(" -r MACHINE remote machine\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(" -a add user\n"); - printf(" -d disable user\n"); - printf(" -e enable user\n"); - printf(" -m machine trust account\n"); - printf(" -n set no password\n"); + if (getuid() == 0 || local_mode) { + printf(" -L local mode (must be first option)\n"); + printf(" -R ORDER name resolve order\n"); + printf(" -j DOMAIN join domain name\n"); + printf(" -a add user\n"); + printf(" -x delete user\n"); + printf(" -d disable user\n"); + printf(" -e enable user\n"); + printf(" -n set no password\n"); + printf(" -m machine trust account\n"); #ifdef WITH_LDAP_SAM - printf(" -w ldap admin password\n"); + printf(" -w ldap admin password\n"); #endif - printf(" -x delete user\n"); - printf(" -j DOMAIN join domain name\n"); - printf(" -R ORDER name resolve order\n"); - - exit(1); -} - -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; - - 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(servicesf,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; - new_passwd = strdup_x("XXXXXX"); - break; - case 'd': - if (!amroot) goto bad_args; - local_flags |= LOCAL_DISABLE_USER; - new_passwd = strdup_x("XXXXXX"); - break; - case 'e': - if (!amroot) goto bad_args; - local_flags |= LOCAL_ENABLE_USER; - break; - case 'm': - if (!amroot) goto bad_args; - local_flags |= LOCAL_TRUST_ACCOUNT; - break; - case 'n': - if (!amroot) goto bad_args; - local_flags |= LOCAL_SET_NO_PASSWORD; - new_passwd = strdup_x("NO PASSWORD"); - break; - case 'j': - if (!amroot) goto bad_args; - new_domain = optarg; - strupper(new_domain); - joining_domain = True; - 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(optarg, '%') + 1, 'X', - strlen(user_password)); - } - - break; - } - case 'h': - default: -bad_args: - usage(); - } } - - argc -= optind; - argv += optind; - - if (joining_domain && (argc != 0)) - usage(); - - switch(argc) { - case 0: - if (!got_username) - fstrcpy(user_name, ""); - break; - case 1: - if (!amroot == 1) { - 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 = strdup_x(argv[1]); - break; - default: - usage(); - } - + exit(1); } /* Initialise client credentials for authenticated pipe access */ @@ -270,16 +117,15 @@ Join a domain using the administrator username and password goto done; \ } -static int join_domain_byuser(char *domain, char *remote, +static int join_domain_byuser(char *domain, char *remote_machine, char *username, char *password) { /* libsmb variables */ - pstring pdc_name; struct nmb_name calling, called; struct ntuser_creds creds; struct cli_state cli; - fstring acct_name; + fstring dest_host, acct_name; struct in_addr dest_ip; TALLOC_CTX *mem_ctx; @@ -303,8 +149,6 @@ static int join_domain_byuser(char *domain, char *remote, NTSTATUS result; int retval = 1; - pstrcpy(pdc_name, remote ? remote : ""); - /* Connect to remote machine */ ZERO_STRUCT(cli); @@ -323,35 +167,17 @@ static int join_domain_byuser(char *domain, char *remote, init_rpcclient_creds(&creds, username, domain, password); cli_init_creds(&cli, &creds); - /* - * If we are given a remote machine assume this is the PDC. - */ - - if(remote == NULL || !strcmp(remote, "*")) { - struct in_addr *ip_list; - int addr_count; - if (!get_dc_list(True /* PDC only*/, domain, &ip_list, &addr_count)) { - fprintf(stderr, "Unable to find the domain controller for domain %s.\n", domain); - return 1; - } - if ((addr_count < 1) || (is_zero_ip(ip_list[0]))) { - fprintf(stderr, "Incorrect entries returned when finding the domain controller for domain %s.\n", domain); - return 1; - } - - if (!lookup_dc_name(global_myname, domain, &ip_list[0], pdc_name)) { - fprintf(stderr, "Unable to lookup the name for the domain controller for domain %s.\n", domain); - return 1; - } - dest_ip = ip_list[0]; + if (!resolve_srv_name(remote_machine, dest_host, &dest_ip)) { + DEBUG(0, ("Could not resolve name %s\n", remote_machine)); + goto done; } - make_nmb_name(&called, pdc_name, 0x20); + make_nmb_name(&called, dns_to_netbios_name(dest_host), 0x20); make_nmb_name(&calling, dns_to_netbios_name(global_myname), 0); - if (!cli_establish_connection(&cli, pdc_name, &dest_ip, &calling, + if (!cli_establish_connection(&cli, dest_host, &dest_ip, &calling, &called, "IPC$", "IPC", False, True)) { - DEBUG(0, ("Error connecting to %s\n", pdc_name)); + DEBUG(0, ("Error connecting to %s\n", dest_host)); goto done; } @@ -475,7 +301,7 @@ static int join_domain_byuser(char *domain, char *remote, encode_pw_buffer((char *)pwbuf, machine_pwd, plen, False); - mdfour( ntpw, (unsigned char *)upw.buffer, plen); + nt_owf_genW(&upw, ntpw); } /* Set password on machine account */ @@ -555,13 +381,13 @@ Join a domain. Old server manager method. static int join_domain(char *domain, char *remote) { - pstring pdc_name; + pstring remote_machine; fstring trust_passwd; unsigned char orig_trust_passwd_hash[16]; DOM_SID domain_sid; BOOL ret; - pstrcpy(pdc_name, remote ? remote : ""); + pstrcpy(remote_machine, remote ? remote : ""); fstrcpy(trust_passwd, global_myname); strlower(trust_passwd); E_md4hash( (uchar *)trust_passwd, orig_trust_passwd_hash); @@ -589,31 +415,23 @@ machine %s in domain %s.\n", global_myname, domain); * If we are given a remote machine assume this is the PDC. */ - if(remote == NULL || !strcmp(remote, "*")) { - struct in_addr *ip_list; - int addr_count; - if (!get_dc_list(True /* PDC only*/, domain, &ip_list, &addr_count)) { - fprintf(stderr, "Unable to find the domain controller for domain %s.\n", domain); - return 1; - } - if ((addr_count < 1) || (is_zero_ip(ip_list[0]))) { - fprintf(stderr, "Incorrect entries returned when finding the domain controller for domain %s.\n", domain); - return 1; - } + if(remote == NULL) { + pstrcpy(remote_machine, lp_passwordserver()); + } - if (!lookup_dc_name(global_myname, domain, &ip_list[0], pdc_name)) { - fprintf(stderr, "Unable to lookup the name for the domain controller for domain %s.\n", domain); - return 1; - } + if(!*remote_machine) { + fprintf(stderr, "No password server list given in smb.conf - \ +unable to join domain.\n"); + return 1; } - if (!fetch_domain_sid( domain, pdc_name, &domain_sid) || + if (!fetch_domain_sid( domain, remote_machine, &domain_sid) || !secrets_store_domain_sid(domain, &domain_sid)) { fprintf(stderr,"Failed to get domain SID. Unable to join domain %s.\n",domain); return 1; } - ret = change_trust_account_password( domain, pdc_name); + ret = change_trust_account_password( domain, remote_machine); if(!ret) { trust_password_delete(domain); @@ -626,6 +444,11 @@ machine %s in domain %s.\n", global_myname, domain); return 0; } +static void set_line_buffering(FILE *f) +{ + setvbuf(f, NULL, _IOLBF, 0); +} + /************************************************************* Utility function to prompt for passwords from stdin. Each password entered must end with a newline. @@ -714,7 +537,7 @@ static BOOL password_change(const char *remote_machine, char *user_name, return False; } ret = remote_password_change(remote_machine, user_name, - old_passwd, new_passwd, err_str, sizeof(err_str)); + old_passwd, new_passwd, err_str, sizeof(err_str)); if(*err_str) fprintf(stderr, err_str); return ret; @@ -747,15 +570,107 @@ 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 joining_domain = False, got_pass = False, got_username = False; + int local_flags = 0; + BOOL stdin_passwd_get = False; + fstring user_name, user_password; +#ifdef WITH_LDAP_SAM + fstring ldap_secret; +#endif + char *new_domain = NULL; + char *new_passwd = NULL; + char *old_passwd = NULL; + char *remote_machine = NULL; + + user_name[0] = '\0'; + + while ((ch = getopt(argc, argv, "axdehmnj:r: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; + new_passwd = strdup_x("XXXXXX"); + break; + case 'd': + local_flags |= LOCAL_DISABLE_USER; + new_passwd = strdup_x("XXXXXX"); + break; + case 'e': + local_flags |= LOCAL_ENABLE_USER; + break; + case 'm': + local_flags |= LOCAL_TRUST_ACCOUNT; + break; + case 'n': + local_flags |= LOCAL_SET_NO_PASSWORD; + new_passwd = strdup_x("NO PASSWORD"); + break; + case 'j': + new_domain = optarg; + strupper(new_domain); + joining_domain = True; + 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(user_name, '%'))) { + *lp = 0; + fstrcpy(user_password, lp + 1); + got_pass = True; + memset(strchr(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) @@ -789,6 +704,9 @@ static int process_root(void) if (joining_domain) { + if (argc != 0) + usage(); + /* Are we joining by specifing an admin username and password? */ @@ -817,6 +735,26 @@ static int process_root(void) * 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 = strdup_x(argv[1]); + break; + default: + usage(); + } + if (!user_name[0] && (pwd = sys_getpwuid(0))) { fstrcpy(user_name, pwd->pw_name); } @@ -902,9 +840,7 @@ static int process_root(void) goto done; } - if(remote_machine) { - printf("Password changed for user %s on %s.\n", user_name, remote_machine ); - } else if(!(local_flags & (LOCAL_ADD_USER|LOCAL_DISABLE_USER|LOCAL_ENABLE_USER|LOCAL_DELETE_USER|LOCAL_SET_NO_PASSWORD))) { + if(!(local_flags & (LOCAL_ADD_USER|LOCAL_DISABLE_USER|LOCAL_ENABLE_USER|LOCAL_DELETE_USER|LOCAL_SET_NO_PASSWORD))) { SAM_ACCOUNT *sampass = NULL; uint16 acct_ctrl; @@ -935,18 +871,55 @@ static int process_root(void) /************************************************************* - Handle password changing for non-root. +handle password changing for non-root *************************************************************/ - -static int process_nonroot(void) +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 = strdup_x(pwd->pw_name); } else { fprintf(stderr,"you don't exist - go away\n"); exit(1); @@ -1000,7 +973,7 @@ static int process_nonroot(void) **********************************************************/ int main(int argc, char **argv) { - BOOL amroot = getuid() == 0; + static pstring servicesf = CONFIGFILE; AllowDebugChange = False; @@ -1008,13 +981,12 @@ int main(int argc, char **argv) set_auth_parameters(argc, argv); #endif /* HAVE_SET_AUTH_PARAMETERS */ - charset_initialise(); - - process_options(argc, argv, amroot); TimeInit(); setup_logging("smbpasswd", True); + charset_initialise(); + if(!initialize_password_db(False)) { fprintf(stderr, "Can't setup password database vectors.\n"); exit(1); @@ -1047,10 +1019,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); } |