diff options
| -rw-r--r-- | source3/utils/smbpasswd.c | 358 | 
1 files changed, 178 insertions, 180 deletions
diff --git a/source3/utils/smbpasswd.c b/source3/utils/smbpasswd.c index de7e66a084..cd046dfb1b 100644 --- a/source3/utils/smbpasswd.c +++ b/source3/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; - -	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; +	int result = 0; -	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();  }  | 
