summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/proto.h26
-rw-r--r--source3/include/smb.h2
-rw-r--r--source3/lib/util.c2
-rw-r--r--source3/lib/util_str.c8
-rw-r--r--source3/lib/util_unistr.c2
-rw-r--r--source3/libsmb/clientgen.c6
-rw-r--r--source3/libsmb/namequery.c12
-rw-r--r--source3/libsmb/nmblib.c2
-rw-r--r--source3/libsmb/smbencrypt.c2
-rw-r--r--source3/utils/smbpasswd.c1316
10 files changed, 710 insertions, 668 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 019e793aa6..888e2af33f 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -258,7 +258,7 @@ BOOL matchname(char *remotehost,struct in_addr addr);
void standard_sub_basic(char *str);
void standard_sub(connection_struct *conn,char *str);
BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask);
-struct hostent *Get_Hostbyname(char *name);
+struct hostent *Get_Hostbyname(const char *name);
BOOL process_exists(int pid);
char *uidtoname(uid_t uid);
char *gidtoname(gid_t gid);
@@ -333,9 +333,9 @@ char *client_addr(int fd);
void set_first_token(char *ptr);
BOOL next_token(char **ptr,char *buff,char *sep, int bufsize);
char **toktocliplist(int *ctok, char *sep);
-int StrCaseCmp(char *s, char *t);
+int StrCaseCmp(const char *s, const char *t);
int StrnCaseCmp(char *s, char *t, int n);
-BOOL strequal(char *s1, char *s2);
+BOOL strequal(const char *s1, const char *s2);
BOOL strnequal(char *s1,char *s2,int n);
BOOL strcsequal(char *s1,char *s2);
void strlower(char *s);
@@ -352,8 +352,8 @@ int count_chars(char *s,char c);
char *safe_strcpy(char *dest,const char *src, int maxlength);
char *safe_strcat(char *dest, char *src, int maxlength);
char *StrCpy(char *dest,char *src);
-char *StrnCpy(char *dest,char *src,int n);
-char *strncpyn(char *dest, char *src,int n, char c);
+char *StrnCpy(char *dest,const char *src,int n);
+char *strncpyn(char *dest, const char *src,int n, char c);
int strhex_to_str(char *p, int len, const char *strhex);
BOOL in_list(char *s,char *list,BOOL casesensitive);
BOOL string_init(char **dest,char *src);
@@ -372,7 +372,7 @@ char *unistr2_to_str(UNISTR2 *str);
uint32 buffer2_to_uint32(BUFFER2 *str);
char *buffer2_to_str(BUFFER2 *str);
char *buffer2_to_multistr(BUFFER2 *str);
-int struni2(uint16 *p, char *buf);
+int struni2(uint16 *p, const char *buf);
char *unistr(char *buf);
int unistrcpy(char *dst, char *src);
@@ -435,12 +435,12 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum,
time_t *w_time, SMB_INO_T *ino);
int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute,
void (*fn)(file_info *, const char *));
-BOOL cli_oem_change_password(struct cli_state *cli, char *user, char *new_password,
- char *old_password);
+BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char *new_password,
+ const char *old_password);
BOOL cli_negprot(struct cli_state *cli);
BOOL cli_session_request(struct cli_state *cli,
struct nmb_name *calling, struct nmb_name *called);
-BOOL cli_connect(struct cli_state *cli, char *host, struct in_addr *ip);
+BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip);
struct cli_state *cli_initialise(struct cli_state *cli);
void cli_shutdown(struct cli_state *cli);
int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num);
@@ -482,12 +482,12 @@ BOOL deal_with_creds(uchar sess_key[8],
BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
struct in_addr to_ip,char *master,char *rname,
void (*fn)(struct packet_struct *));
-struct in_addr *name_query(int fd,char *name,int name_type, BOOL bcast,BOOL recurse,
+struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOOL recurse,
struct in_addr to_ip, int *count, void (*fn)(struct packet_struct *));
FILE *startlmhosts(char *fname);
BOOL getlmhostsent( FILE *fp, char *name, int *name_type, struct in_addr *ipaddr);
void endlmhosts(FILE *fp);
-BOOL resolve_name(char *name, struct in_addr *return_ip, int name_type);
+BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type);
BOOL find_master_ip(char *group, struct in_addr *master_ip);
/*The following definitions come from libsmb/nmblib.c */
@@ -497,7 +497,7 @@ char *namestr(struct nmb_name *n);
struct packet_struct *copy_packet(struct packet_struct *packet);
void free_packet(struct packet_struct *packet);
struct packet_struct *read_packet(int fd,enum packet_type packet_type);
-void make_nmb_name( struct nmb_name *n, char *name, int type, char *this_scope );
+void make_nmb_name( struct nmb_name *n, const char *name, int type, const char *this_scope );
BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2);
BOOL send_packet(struct packet_struct *p);
struct packet_struct *receive_packet(int fd,enum packet_type type,int t);
@@ -540,7 +540,7 @@ void nt_lm_owf_gen(char *pwd, uchar nt_p16[16], uchar p16[16]);
void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24]);
void NTLMSSPOWFencrypt(uchar passwd[8], uchar *ntlmchalresp, uchar p24[24]);
void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24);
-BOOL make_oem_passwd_hash(char data[516], char *passwd, uchar old_pw_hash[16], BOOL unicode);
+BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[16], BOOL unicode);
/*The following definitions come from libsmb/smberr.c */
diff --git a/source3/include/smb.h b/source3/include/smb.h
index db7b251d65..47a8869a48 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -41,7 +41,7 @@
#define IS_BITS_SET_SOME(var,bit) (((var)&(bit))!=0)
#define IS_BITS_CLR_ALL(var,bit) (((var)&(~(bit)))==0)
-#define PTR_DIFF(p1,p2) ((ptrdiff_t)(((char *)(p1)) - (char *)(p2)))
+#define PTR_DIFF(p1,p2) ((ptrdiff_t)(((const char *)(p1)) - (const char *)(p2)))
typedef int BOOL;
diff --git a/source3/lib/util.c b/source3/lib/util.c
index f1fae9155c..2be1fcaf6f 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -2386,7 +2386,7 @@ BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
a wrapper for gethostbyname() that tries with all lower and all upper case
if the initial name fails
****************************************************************************/
-struct hostent *Get_Hostbyname(char *name)
+struct hostent *Get_Hostbyname(const char *name)
{
char *name2 = strdup(name);
struct hostent *ret;
diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c
index 996273bf3a..02fa892d7b 100644
--- a/source3/lib/util_str.c
+++ b/source3/lib/util_str.c
@@ -115,7 +115,7 @@ char **toktocliplist(int *ctok, char *sep)
/*******************************************************************
case insensitive string compararison
********************************************************************/
-int StrCaseCmp(char *s, char *t)
+int StrCaseCmp(const char *s, const char *t)
{
/* compare until we run out of string, either t or s, or find a difference */
/* We *must* use toupper rather than tolower here due to the
@@ -272,7 +272,7 @@ int StrnCaseCmp(char *s, char *t, int n)
/*******************************************************************
compare 2 strings
********************************************************************/
-BOOL strequal(char *s1, char *s2)
+BOOL strequal(const char *s1, const char *s2)
{
if (s1 == s2) return(True);
if (!s1 || !s2) return(False);
@@ -819,7 +819,7 @@ char *StrCpy(char *dest,char *src)
/****************************************************************************
like strncpy but always null terminates. Make sure there is room!
****************************************************************************/
-char *StrnCpy(char *dest,char *src,int n)
+char *StrnCpy(char *dest,const char *src,int n)
{
char *d = dest;
if (!dest) return(NULL);
@@ -837,7 +837,7 @@ char *StrnCpy(char *dest,char *src,int n)
like strncpy but copies up to the character marker. always null terminates.
returns a pointer to the character marker in the source string (src).
****************************************************************************/
-char *strncpyn(char *dest, char *src,int n, char c)
+char *strncpyn(char *dest, const char *src,int n, char c)
{
char *p;
int str_len;
diff --git a/source3/lib/util_unistr.c b/source3/lib/util_unistr.c
index 49fb729267..c58820cfec 100644
--- a/source3/lib/util_unistr.c
+++ b/source3/lib/util_unistr.c
@@ -189,7 +189,7 @@ return number of unicode chars copied, excluding the null character.
only handles ascii strings
********************************************************************/
#define MAXUNI 1024
-int struni2(uint16 *p, char *buf)
+int struni2(uint16 *p, const char *buf)
{
int len = 0;
diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c
index fc4c7f1d5d..b4ca7a1d77 100644
--- a/source3/libsmb/clientgen.c
+++ b/source3/libsmb/clientgen.c
@@ -2087,8 +2087,8 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute,
Send a SamOEMChangePassword command
****************************************************************************/
-BOOL cli_oem_change_password(struct cli_state *cli, char *user, char *new_password,
- char *old_password)
+BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char *new_password,
+ const char *old_password)
{
char param[16+sizeof(fstring)];
char data[532];
@@ -2317,7 +2317,7 @@ retry:
/****************************************************************************
open the client sockets
****************************************************************************/
-BOOL cli_connect(struct cli_state *cli, char *host, struct in_addr *ip)
+BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip)
{
extern struct in_addr ipzero;
diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c
index 0e92e6b5dd..f06ecc94e4 100644
--- a/source3/libsmb/namequery.c
+++ b/source3/libsmb/namequery.c
@@ -194,7 +194,7 @@ BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
returns an array of IP addresses or NULL if none
*count will be set to the number of addresses returned
****************************************************************************/
-struct in_addr *name_query(int fd,char *name,int name_type, BOOL bcast,BOOL recurse,
+struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOOL recurse,
struct in_addr to_ip, int *count, void (*fn)(struct packet_struct *))
{
BOOL found=False;
@@ -440,7 +440,7 @@ void endlmhosts(FILE *fp)
/********************************************************
resolve via "bcast" method
*********************************************************/
-static BOOL resolve_bcast(char *name, struct in_addr *return_ip, int name_type)
+static BOOL resolve_bcast(const char *name, struct in_addr *return_ip, int name_type)
{
int sock, i;
@@ -486,7 +486,7 @@ static BOOL resolve_bcast(char *name, struct in_addr *return_ip, int name_type)
/********************************************************
resolve via "wins" method
*********************************************************/
-static BOOL resolve_wins(char *name, struct in_addr *return_ip, int name_type)
+static BOOL resolve_wins(const char *name, struct in_addr *return_ip, int name_type)
{
int sock;
struct in_addr wins_ip;
@@ -536,7 +536,7 @@ static BOOL resolve_wins(char *name, struct in_addr *return_ip, int name_type)
/********************************************************
resolve via "lmhosts" method
*********************************************************/
-static BOOL resolve_lmhosts(char *name, struct in_addr *return_ip, int name_type)
+static BOOL resolve_lmhosts(const char *name, struct in_addr *return_ip, int name_type)
{
/*
* "lmhosts" means parse the local lmhosts file.
@@ -566,7 +566,7 @@ static BOOL resolve_lmhosts(char *name, struct in_addr *return_ip, int name_type
/********************************************************
resolve via "hosts" method
*********************************************************/
-static BOOL resolve_hosts(char *name, struct in_addr *return_ip)
+static BOOL resolve_hosts(const char *name, struct in_addr *return_ip)
{
/*
* "host" means do a localhost, or dns lookup.
@@ -589,7 +589,7 @@ static BOOL resolve_hosts(char *name, struct in_addr *return_ip)
or NetBIOS name. This uses the name switch in the
smb.conf to determine the order of name resolution.
*********************************************************/
-BOOL resolve_name(char *name, struct in_addr *return_ip, int name_type)
+BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type)
{
int i;
BOOL pure_address = True;
diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c
index 87f483e9fd..6314a9076b 100644
--- a/source3/libsmb/nmblib.c
+++ b/source3/libsmb/nmblib.c
@@ -762,7 +762,7 @@ static int build_dgram(char *buf,struct packet_struct *p)
/*******************************************************************
build a nmb name
*******************************************************************/
-void make_nmb_name( struct nmb_name *n, char *name, int type, char *this_scope )
+void make_nmb_name( struct nmb_name *n, const char *name, int type, const char *this_scope )
{
memset( (char *)n, '\0', sizeof(struct nmb_name) );
StrnCpy( n->name, name, 15 );
diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c
index 5017b33c07..9234088404 100644
--- a/source3/libsmb/smbencrypt.c
+++ b/source3/libsmb/smbencrypt.c
@@ -190,7 +190,7 @@ void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24)
#endif
}
-BOOL make_oem_passwd_hash(char data[516], char *passwd, uchar old_pw_hash[16], BOOL unicode)
+BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[16], BOOL unicode)
{
int new_pw_len = strlen(passwd) * (unicode ? 2 : 1);
diff --git a/source3/utils/smbpasswd.c b/source3/utils/smbpasswd.c
index e1904f9c96..09aa0be9d6 100644
--- a/source3/utils/smbpasswd.c
+++ b/source3/utils/smbpasswd.c
@@ -23,697 +23,739 @@ extern pstring scope;
extern pstring myhostname;
extern pstring global_myname;
extern fstring global_myworkgroup;
+extern int DEBUGLEVEL;
-static char *prog_name;
/*********************************************************
- Print command usage on stderr and die.
+a strdup with exit
**********************************************************/
+static char *xstrdup(char *s)
+{
+ s = strdup(s);
+ if (!s) {
+ fprintf(stderr,"out of memory\n");
+ exit(1);
+ }
+ return s;
+}
-static void usage(char *name, BOOL is_root)
+
+/*********************************************************
+ Print command usage on stderr and die.
+**********************************************************/
+static void usage(void)
{
- if(is_root)
- fprintf(stderr, "Usage is : %s [-D DEBUGLEVEL] [-h] [-a] [-d] [-e] [-m] [-n] [-s] [username] [password]\n\
-%s: [-R <name resolve order>] [-D DEBUGLEVEL] [-j DOMAINNAME] [-r machine] [-U remote_username] [username] [password]\n%s: [-h]\n", name, name, name);
- else
- fprintf(stderr, "Usage is : %s [-h] [-s] [-D DEBUGLEVEL] [-r machine] [-U remote_username] [password]\n", name);
+ if (getuid() == 0) {
+ printf("smbpasswd [options] [username] [password]\n");
+ } else {
+ printf("smbpasswd [options] [password]\n");
+ }
+ printf("options:\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");
+
+ if (getuid() == 0) {
+ printf(" -R ORDER name resolve order\n");
+ printf(" -j DOMAIN join domain name\n");
+ printf(" -a add user\n");
+ printf(" -d delete user\n");
+ printf(" -e enable user\n");
+ printf(" -n set no password\n");
+ printf(" -m machine trust account\n");
+ }
exit(1);
}
/*********************************************************
Join a domain.
**********************************************************/
+static int join_domain(char *domain, char *remote)
+{
+ pstring remote_machine;
+ fstring trust_passwd;
+ unsigned char orig_trust_passwd_hash[16];
+ BOOL ret;
+
+ pstrcpy(remote_machine, remote ? remote : "");
+ fstrcpy(trust_passwd, global_myname);
+ strlower(trust_passwd);
+ E_md4hash( (uchar *)trust_passwd, orig_trust_passwd_hash);
+
+ /* Ensure that we are not trying to join a
+ domain if we are locally set up as a domain
+ controller. */
+
+ if(strequal(remote, global_myname)) {
+ fprintf(stderr, "Cannot join domain %s as the domain controller name is our own. We cannot be a domain controller for a domain and also be a domain member.\n", domain);
+ return 1;
+ }
+
+ /*
+ * Create the machine account password file.
+ */
+ if(!trust_password_lock( domain, global_myname, True)) {
+ fprintf(stderr, "unable to open the machine account password file for \
+machine %s in domain %s.\n", global_myname, domain);
+ return 1;
+ }
+
+ /*
+ * Write the old machine account password.
+ */
+
+ if(!set_trust_account_password( orig_trust_passwd_hash)) {
+ fprintf(stderr, "unable to write the machine account password for \
+machine %s in domain %s.\n", global_myname, domain);
+ trust_password_unlock();
+ return 1;
+ }
+
+ /*
+ * If we are given a remote machine assume this is the PDC.
+ */
+
+ if(remote == NULL) {
+ pstrcpy(remote_machine, lp_passwordserver());
+ }
+
+ if(!*remote_machine) {
+ fprintf(stderr, "No password server list given in smb.conf - \
+unable to join domain.\n");
+ trust_password_unlock();
+ return 1;
+ }
+
+ ret = change_trust_account_password( domain, remote_machine);
+ trust_password_unlock();
+
+ if(!ret) {
+ trust_password_delete( domain, global_myname);
+ fprintf(stderr,"Unable to join domain %s.\n",domain);
+ } else {
+ printf("Joined domain %s.\n",domain);
+ }
+
+ return (int)ret;
+}
+
-static int join_domain( char *domain, char *remote)
+static void set_line_buffering(FILE *f)
{
- pstring remote_machine;
- fstring trust_passwd;
- unsigned char orig_trust_passwd_hash[16];
- BOOL ret;
-
- pstrcpy(remote_machine, remote ? remote : "");
- fstrcpy(trust_passwd, global_myname);
- strlower(trust_passwd);
- E_md4hash( (uchar *)trust_passwd, orig_trust_passwd_hash);
-
- /* Ensure that we are not trying to join a
- domain if we are locally set up as a domain
- controller. */
-
- if(strequal(remote, global_myname)) {
- fprintf(stderr, "%s: Cannot join domain %s as the domain controller name is our own. \
-We cannot be a domain controller for a domain and also be a domain member.\n", prog_name, domain);
- return 1;
- }
-
- /*
- * Create the machine account password file.
- */
- if(!trust_password_lock( domain, global_myname, True)) {
- fprintf(stderr, "%s: unable to open the machine account password file for \
-machine %s in domain %s.\n", prog_name, global_myname, domain);
- return 1;
- }
-
- /*
- * Write the old machine account password.
- */
-
- if(!set_trust_account_password( orig_trust_passwd_hash)) {
- fprintf(stderr, "%s: unable to write the machine account password for \
-machine %s in domain %s.\n", prog_name, global_myname, domain);
- trust_password_unlock();
- return 1;
- }
-
- /*
- * If we are given a remote machine assume this is the PDC.
- */
-
- if(remote == NULL)
- pstrcpy(remote_machine, lp_passwordserver());
-
- if(!*remote_machine) {
- fprintf(stderr, "%s: No password server list given in smb.conf - \
-unable to join domain.\n", prog_name);
- trust_password_unlock();
- return 1;
- }
-
- ret = change_trust_account_password( domain, remote_machine);
- trust_password_unlock();
-
- if(!ret) {
- trust_password_delete( domain, global_myname);
- fprintf(stderr,"%s: Unable to join domain %s.\n", prog_name, domain);
- } else {
- printf("%s: Joined domain %s.\n", prog_name, domain);
- }
-
- return (int)ret;
+ setvbuf(f, NULL, _IOLBF, 0);
}
/*************************************************************
Utility function to prompt for passwords from stdin. Each
password entered must end with a newline.
*************************************************************/
-
static char *stdin_new_passwd(void)
{
- static fstring new_passwd;
- size_t len;
-
- memset( new_passwd, '\0', sizeof(new_passwd));
-
- /*
- * if no error is reported from fgets() and string at least contains
- * the newline that ends the password, then replace the newline with
- * a null terminator.
- */
- if ( fgets(new_passwd, sizeof(new_passwd), stdin) != NULL) {
- if ((len = strlen(new_passwd)) > 0) {
- if(new_passwd[len-1] == '\n')
- new_passwd[len - 1] = 0;
- }
- }
- return(new_passwd);
+ static fstring new_passwd;
+ size_t len;
+
+ ZERO_STRUCT(new_passwd);
+
+ /*
+ * if no error is reported from fgets() and string at least contains
+ * the newline that ends the password, then replace the newline with
+ * a null terminator.
+ */
+ if ( fgets(new_passwd, sizeof(new_passwd), stdin) != NULL) {
+ if ((len = strlen(new_passwd)) > 0) {
+ if(new_passwd[len-1] == '\n')
+ new_passwd[len - 1] = 0;
+ }
+ }
+ return(new_passwd);
}
+
/*************************************************************
Utility function to get passwords via tty or stdin
Used if the '-s' option is set to silently get passwords
to enable scripting.
*************************************************************/
-
static char *get_pass( char *prompt, BOOL stdin_get)
{
- if (stdin_get)
- return( stdin_new_passwd());
- else
- return( getpass( prompt));
+ char *p;
+ if (stdin_get) {
+ p = stdin_new_passwd();
+ } else {
+ p = getpass(prompt);
+ }
+ return xstrdup(p);
}
/*************************************************************
Utility function to prompt for new password.
*************************************************************/
-
-static void prompt_for_new_password(char *new_passwd, BOOL stdin_get)
+static char *prompt_for_new_password(BOOL stdin_get)
{
- char *p;
+ char *p;
+ fstring new_passwd;
- new_passwd[0] = '\0';
+ ZERO_STRUCT(new_passwd);
- p = get_pass("New SMB password:", stdin_get);
+ p = get_pass("New SMB password:", stdin_get);
- strncpy(new_passwd, p, sizeof(fstring));
- new_passwd[sizeof(fstring)-1] = '\0';
+ fstrcpy(new_passwd, p);
- p = get_pass("Retype new SMB password:", stdin_get);
+ p = get_pass("Retype new SMB password:", stdin_get);
- if (strncmp(p, new_passwd, sizeof(fstring)-1))
- {
- fprintf(stderr, "%s: Mismatch - password unchanged.\n", prog_name);
- exit(1);
- }
+ if (strcmp(p, new_passwd)) {
+ fprintf(stderr, "Mismatch - password unchanged.\n");
+ return NULL;
+ }
- if (new_passwd[0] == '\0') {
- printf("Password not set\n");
- exit(0);
- }
+ return xstrdup(p);
}
-/*********************************************************
- Start here.
-**********************************************************/
-int main(int argc, char **argv)
-{
- extern char *optarg;
- extern int optind;
- extern int DEBUGLEVEL;
- uid_t real_uid;
- uid_t eff_uid;
- struct passwd *pwd = NULL;
- fstring old_passwd;
- fstring new_passwd;
- uchar new_p16[16];
- uchar new_nt_p16[16];
- char *p;
- struct smb_passwd *smb_pwent;
- FILE *fp;
- int ch;
- int err;
- BOOL is_root = False;
- pstring user_name;
- BOOL remote_user_name = False;
- char *remote_machine = NULL;
- BOOL add_user = False;
- BOOL got_new_pass = False;
- BOOL trust_account = False;
- BOOL disable_user = False;
- BOOL enable_user = False;
- BOOL set_no_password = False;
- BOOL joining_domain = False;
- BOOL stdin_passwd_get = False;
- char *new_domain = NULL;
- pstring servicesf = CONFIGFILE;
- void *vp;
- struct nmb_name calling, called;
-
-
- new_passwd[0] = '\0';
- user_name[0] = '\0';
-
- memset(old_passwd, '\0', sizeof(old_passwd));
- memset(new_passwd, '\0', sizeof(new_passwd));
- prog_name = argv[0];
- TimeInit();
-
- setup_logging(prog_name,True);
-
- charset_initialise();
-
- if(!initialize_password_db()) {
- fprintf(stderr, "%s: Can't setup password database vectors.\n", prog_name);
- exit(1);
- }
-
- if (!lp_load(servicesf,True,False,False)) {
- fprintf(stderr, "%s: Can't load %s - run testparm to debug it\n", prog_name, servicesf);
- exit(1);
- }
-
- if(!get_myname(myhostname,NULL)) {
- fprintf(stderr, "%s: unable to get my hostname.\n", prog_name );
- exit(1);
- }
-
- /*
- * Set the machine NETBIOS name if not already
- * set from the config file.
- */
-
- if (!*global_myname)
- {
- fstrcpy( global_myname, myhostname );
- p = strchr( global_myname, '.' );
- if (p)
- *p = 0;
- }
- strupper( global_myname );
-
- codepage_initialise(lp_client_code_page());
-
- /* Get the real and effective uids */
- real_uid = getuid();
- eff_uid = geteuid();
-
- /* Check the effective uid */
- if ((eff_uid == (uid_t)0) && (real_uid != (uid_t)0)) {
- fprintf(stderr, "%s: Must *NOT* be setuid root.\n", prog_name);
- exit(1);
- }
-
- is_root = (eff_uid == (uid_t)0);
-
- while ((ch = getopt(argc, argv, "adehmnj:r:sR:D:U:")) != EOF) {
- switch(ch) {
- case 'a':
- if(is_root)
- add_user = True;
- else
- usage(prog_name, is_root);
- break;
- case 'd':
- if(is_root) {
- disable_user = True;
- got_new_pass = True;
- fstrcpy(new_passwd, "XXXXXX");
- } else
- usage(prog_name, is_root);
- break;
- case 'e':
- if(is_root) {
- enable_user = True;
- got_new_pass = True;
- fstrcpy(new_passwd, "XXXXXX");
- } else
- usage(prog_name, is_root);
- break;
- case 'D':
- DEBUGLEVEL = atoi(optarg);
- break;
- case 'n':
- if(is_root) {
- set_no_password = True;
- got_new_pass = True;
- fstrcpy(new_passwd, "NO PASSWORD");
- } else
- usage(prog_name, is_root);
- case 'r':
- remote_machine = optarg;
- break;
- case 's':
- /*
- * Ensure stdin/stdout are line buffered.
- */
- if (setvbuf( stdin, NULL, _IOLBF, 0) != 0) {
- fprintf(stderr, "%s: setvbuf error on stdin. Error was %s\n", prog_name, strerror(errno));
- exit(1);
- }
-
- if (setvbuf( stdout, NULL, _IOLBF, 0) != 0) {
- fprintf(stderr, "%s: setvbuf error on stdout. Error was %s\n", prog_name, strerror(errno));
- exit(1);
- }
-
- if (setvbuf( stderr, NULL, _IOLBF, 0) != 0) {
- fprintf(stderr, "%s: setvbuf error on stderr. Error was %s\n", prog_name, strerror(errno));
- perror("setvbuf error on stdout");
- exit(1);
- }
-
- stdin_passwd_get = True;
- break;
- case 'R':
- if(is_root) {
- lp_set_name_resolve_order(optarg);
- break;
- } else
- usage(prog_name, is_root);
- case 'm':
- if(is_root) {
- trust_account = True;
- } else
- usage(prog_name, is_root);
- break;
- case 'j':
- if(is_root) {
- new_domain = optarg;
- strupper(new_domain);
- joining_domain = True;
- } else
- usage(prog_name, is_root);
- break;
- case 'U':
- remote_user_name = True;
- pstrcpy(user_name, optarg);
- break;
- case 'h':
- default:
- usage(prog_name, is_root);
- }
- }
-
- argc -= optind;
- argv += optind;
-
- if (!is_root && remote_user_name && !remote_machine) {
- fprintf(stderr, "%s: You can only use -U with -r.\n", prog_name);
- usage(prog_name, False);
- }
-
- /*
- * Ensure add_user and either remote machine or join domain are
- * not both set.
- */
-
- if(add_user && ((remote_machine != NULL) || joining_domain))
- usage(prog_name, True);
-
- /*
- * Deal with joining a domain.
- */
- if(joining_domain && argc != 0)
- usage(prog_name, True);
-
- if(joining_domain) {
- return join_domain( new_domain, remote_machine);
- }
-
- if(is_root) {
-
- /*
- * Deal with root - can add a user, but only locally.
- */
-
- switch(argc) {
- case 0:
- break;
- case 1:
- /* If we are root we can change another's password. */
- pstrcpy(user_name, argv[0]);
- break;
- case 2:
- pstrcpy(user_name, argv[0]);
- fstrcpy(new_passwd, argv[1]);
- got_new_pass = True;
- break;
- default:
- usage(prog_name, True);
- }
-
- if(*user_name) {
-
- if(trust_account) {
- int username_len = strlen(user_name);
- if(username_len >= sizeof(pstring) - 1) {
- fprintf(stderr, "%s: machine account name too long.\n", user_name);
- exit(1);
- }
-
- if(user_name[username_len-1] != '$') {
- user_name[username_len] = '$';
- user_name[username_len+1] = '\0';
- }
- }
-
- if(!remote_machine && ((pwd = Get_Pwnam(user_name, True)) == NULL)) {
- fprintf(stderr, "%s: User \"%s\" was not found in system password file.\n",
- prog_name, user_name);
- exit(1);
- }
- } else {
- if((pwd = getpwuid(eff_uid)) != NULL)
- pstrcpy( user_name, pwd->pw_name);
- }
-
- } else {
-
- if(add_user) {
- fprintf(stderr, "%s: Only root can add a user.\n", prog_name);
- usage(prog_name, False);
- }
-
- if(disable_user) {
- fprintf(stderr, "%s: Only root can disable a user.\n", prog_name);
- usage(prog_name, False);
- }
-
- if(enable_user) {
- fprintf(stderr, "%s: Only root can enable a user.\n", prog_name);
- usage(prog_name, False);
- }
-
- if(argc > 1)
- usage(prog_name, False);
-
- if(argc == 1) {
- fstrcpy(new_passwd, argv[0]);
- got_new_pass = True;
- }
-
- if(!remote_user_name && ((pwd = getpwuid(eff_uid)) != NULL))
- pstrcpy( user_name, pwd->pw_name);
-
- /*
- * A non-root user is always setting a password
- * via a remote machine (even if that machine is
- * localhost).
- */
-
- if(remote_machine == NULL)
- remote_machine = "127.0.0.1";
- }
-
- if (*user_name == '\0') {
- fprintf(stderr, "%s: Unable to get a user name for password change.\n", prog_name);
- exit(1);
- }
-
- /*
- * If we are adding a machine account then pretend
- * we already have the new password, we will be using
- * the machinename as the password.
- */
-
- if(add_user && trust_account) {
- got_new_pass = True;
- strncpy(new_passwd, user_name, sizeof(fstring));
- new_passwd[sizeof(fstring)-1] = '\0';
- strlower(new_passwd);
- if(new_passwd[strlen(new_passwd)-1] == '$')
- new_passwd[strlen(new_passwd)-1] = '\0';
- }
-
- /*
- * If we are root we don't ask for the old password (unless it's on a
- * remote machine.
- */
-
- if (remote_machine != NULL) {
- p = get_pass("Old SMB password:",stdin_passwd_get);
- fstrcpy(old_passwd, p);
- }
-
- if (!got_new_pass)
- prompt_for_new_password(new_passwd,stdin_passwd_get);
-
- if (new_passwd[0] == '\0') {
- printf("Password not set\n");
- exit(0);
- }
-
- /*
- * Now do things differently depending on if we're changing the
- * password on a remote machine. Remember - a normal user is
- * always using this code, looping back to the local smbd.
- */
-
- if(remote_machine != NULL) {
- struct cli_state cli;
- struct in_addr ip;
-
- if(!resolve_name( remote_machine, &ip, 0x20)) {
- fprintf(stderr, "%s: unable to find an IP address for machine %s.\n",
- prog_name, remote_machine );
- exit(1);
- }
+/*************************************************************
+change a password on a remote machine using IPC calls
+*************************************************************/
+static BOOL remote_password_change(const char *remote_machine, const char *user_name,
+ const char *old_passwd, const char *new_passwd)
+{
+ struct nmb_name calling, called;
+ struct cli_state cli;
+ struct in_addr ip;
+
+ if(!resolve_name( remote_machine, &ip, 0x20)) {
+ fprintf(stderr, "unable to find an IP address for machine %s.\n",
+ remote_machine );
+ return False;
+ }
- ZERO_STRUCT(cli);
+ ZERO_STRUCT(cli);
- if (!cli_initialise(&cli) || !cli_connect(&cli, remote_machine, &ip)) {
- fprintf(stderr, "%s: unable to connect to SMB server on machine %s. Error was : %s.\n",
- prog_name, remote_machine, cli_errstr(&cli) );
- exit(1);
- }
+ if (!cli_initialise(&cli) || !cli_connect(&cli, remote_machine, &ip)) {
+ fprintf(stderr, "unable to connect to SMB server on machine %s. Error was : %s.\n",
+ remote_machine, cli_errstr(&cli) );
+ return False;
+ }
make_nmb_name(&calling, global_myname , 0x0 , scope);
make_nmb_name(&called , remote_machine, 0x20, scope);
-
- if (!cli_session_request(&cli, &calling, &called))
- {
- fprintf(stderr, "%s: machine %s rejected the session setup. Error was : %s.\n",
- prog_name, remote_machine, cli_errstr(&cli) );
- cli_shutdown(&cli);
- exit(1);
- }
+
+ if (!cli_session_request(&cli, &calling, &called)) {
+ fprintf(stderr, "machine %s rejected the session setup. Error was : %s.\n",
+ remote_machine, cli_errstr(&cli) );
+ cli_shutdown(&cli);
+ return False;
+ }
- cli.protocol = PROTOCOL_NT1;
-
- if (!cli_negprot(&cli)) {
- fprintf(stderr, "%s: machine %s rejected the negotiate protocol. Error was : %s.\n",
- prog_name, remote_machine, cli_errstr(&cli) );
- cli_shutdown(&cli);
- exit(1);
- }
+ cli.protocol = PROTOCOL_NT1;
+
+ if (!cli_negprot(&cli)) {
+ fprintf(stderr, "machine %s rejected the negotiate protocol. Error was : %s.\n",
+ remote_machine, cli_errstr(&cli) );
+ cli_shutdown(&cli);
+ return False;
+ }
- /*
- * We should connect as the anonymous user here, in case
- * the server has "must change password" checked...
- * Thanks to <Nicholas.S.Jenkins@cdc.com> for this fix.
- */
-
- if (!cli_session_setup(&cli, "", "", 0, "", 0, "")) {
- fprintf(stderr, "%s: machine %s rejected the session setup. Error was : %s.\n",
- prog_name, remote_machine, cli_errstr(&cli) );
- cli_shutdown(&cli);
- exit(1);
- }
-
- if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) {
- fprintf(stderr, "%s: machine %s rejected the tconX on the IPC$ share. Error was : %s.\n",
- prog_name, remote_machine, cli_errstr(&cli) );
- cli_shutdown(&cli);
- exit(1);
- }
-
- if(!cli_oem_change_password(&cli, user_name, new_passwd, old_passwd)) {
- fprintf(stderr, "%s: machine %s rejected the password change: Error was : %s.\n",
- prog_name, remote_machine, cli_errstr(&cli) );
- cli_shutdown(&cli);
- exit(1);
- }
-
- cli_shutdown(&cli);
- exit(0);
- }
-
- /*
- * Check for a machine account.
- */
-
- if(trust_account && !pwd) {
- fprintf(stderr, "%s: User %s does not exist in system password file \
-(usually /etc/passwd). Cannot add machine account without a valid system user.\n",
- prog_name, user_name);
- exit(1);
- }
-
- /* Calculate the MD4 hash (NT compatible) of the new password. */
-
- nt_lm_owf_gen( new_passwd, new_nt_p16, new_p16);
-
- /*
- * Open the smbpaswd file.
- */
- vp = startsmbpwent(True);
- if (!vp && errno == ENOENT) {
- fprintf(stderr,"%s: smbpasswd file did not exist - attempting to create it.\n", prog_name);
- fp = fopen(lp_smb_passwd_file(), "w");
- if (fp) {
- fprintf(fp, "# Samba SMB password file\n");
- fclose(fp);
- vp = startsmbpwent(True);
- }
- }
- if (!vp) {
- err = errno;
- fprintf(stderr, "%s: Failed to open password file %s.\n",
- prog_name, lp_smb_passwd_file());
- errno = err;
- perror(prog_name);
- exit(err);
- }
+ /*
+ * We should connect as the anonymous user here, in case
+ * the server has "must change password" checked...
+ * Thanks to <Nicholas.S.Jenkins@cdc.com> for this fix.
+ */
+
+ if (!cli_session_setup(&cli, "", "", 0, "", 0, "")) {
+ fprintf(stderr, "machine %s rejected the session setup. Error was : %s.\n",
+ remote_machine, cli_errstr(&cli) );
+ cli_shutdown(&cli);
+ return False;
+ }
+
+ if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) {
+ fprintf(stderr, "machine %s rejected the tconX on the IPC$ share. Error was : %s.\n",
+ remote_machine, cli_errstr(&cli) );
+ cli_shutdown(&cli);
+ return False;
+ }
+
+ if(!cli_oem_change_password(&cli, user_name, new_passwd, old_passwd)) {
+ fprintf(stderr, "machine %s rejected the password change: Error was : %s.\n",
+ remote_machine, cli_errstr(&cli) );
+ cli_shutdown(&cli);
+ return False;
+ }
+
+ cli_shutdown(&cli);
+ return True;
+}
+
+
+/*************************************************************
+add a new user to the local smbpasswd file
+*************************************************************/
+static BOOL add_new_user(char *user_name, uid_t uid, BOOL trust_account,
+ BOOL disable_user, BOOL set_no_password,
+ char *new_p16, char *new_nt_p16)
+{
+ struct smb_passwd new_smb_pwent;
+
+ /* Create a new smb passwd entry and set it to the given password. */
+ new_smb_pwent.smb_userid = uid;
+ new_smb_pwent.smb_name = user_name;
+ new_smb_pwent.smb_passwd = NULL;
+ new_smb_pwent.smb_nt_passwd = NULL;
+ new_smb_pwent.acct_ctrl = (trust_account ? ACB_WSTRUST : ACB_NORMAL);
+
+ if(disable_user) {
+ new_smb_pwent.acct_ctrl |= ACB_DISABLED;
+ } else if (set_no_password) {
+ new_smb_pwent.acct_ctrl |= ACB_PWNOTREQ;
+ } else {
+ new_smb_pwent.smb_passwd = new_p16;
+ new_smb_pwent.smb_nt_passwd = new_nt_p16;
+ }
+
+ return add_smbpwd_entry(&new_smb_pwent);
+}
+
+
+/*************************************************************
+change a password entry in the local smbpasswd file
+*************************************************************/
+static BOOL local_password_change(char *user_name, BOOL trust_account, BOOL add_user,
+ BOOL enable_user, BOOL disable_user, BOOL set_no_password,
+ char *new_passwd)
+{
+ struct passwd *pwd;
+ void *vp;
+ struct smb_passwd *smb_pwent;
+ uchar new_p16[16];
+ uchar new_nt_p16[16];
+
+ pwd = getpwnam(user_name);
+
+ /*
+ * Check for a machine account.
+ */
+
+ if(trust_account && !pwd) {
+ fprintf(stderr, "User %s does not exist in system password file (usually /etc/passwd). Cannot add machine account without a valid system user.\n",
+ user_name);
+ return False;
+ }
+
+ /* Calculate the MD4 hash (NT compatible) of the new password. */
+ nt_lm_owf_gen(new_passwd, new_nt_p16, new_p16);
+
+ /*
+ * Open the smbpaswd file.
+ */
+ vp = startsmbpwent(True);
+ if (!vp && errno == ENOENT) {
+ FILE *fp;
+ fprintf(stderr,"smbpasswd file did not exist - attempting to create it.\n");
+ fp = fopen(lp_smb_passwd_file(), "w");
+ if (fp) {
+ fprintf(fp, "# Samba SMB password file\n");
+ fclose(fp);
+ vp = startsmbpwent(True);
+ }
+ }
+
+ if (!vp) {
+ perror(lp_smb_passwd_file());
+ return False;
+ }
- /* Get the smb passwd entry for this user */
- smb_pwent = getsmbpwnam(user_name);
- if (smb_pwent == NULL) {
- if(add_user == False) {
- fprintf(stderr, "%s: Failed to find entry for user %s.\n",
- prog_name, pwd->pw_name);
- endsmbpwent(vp);
- exit(1);
- }
-
- /* Create a new smb passwd entry and set it to the given password. */
- {
- struct smb_passwd new_smb_pwent;
-
- new_smb_pwent.smb_userid = pwd->pw_uid;
- new_smb_pwent.smb_name = pwd->pw_name;
- new_smb_pwent.smb_passwd = NULL;
- new_smb_pwent.smb_nt_passwd = NULL;
- new_smb_pwent.acct_ctrl = (trust_account ? ACB_WSTRUST : ACB_NORMAL);
-
- if(disable_user) {
- new_smb_pwent.acct_ctrl |= ACB_DISABLED;
- } else if (set_no_password) {
- new_smb_pwent.acct_ctrl |= ACB_PWNOTREQ;
- } else {
- new_smb_pwent.smb_passwd = new_p16;
- new_smb_pwent.smb_nt_passwd = new_nt_p16;
- }
-
- if(add_smbpwd_entry(&new_smb_pwent) == False) {
- fprintf(stderr, "%s: Failed to add entry for user %s.\n",
- prog_name, pwd->pw_name);
- endsmbpwent(vp);
- exit(1);
- }
-
- endsmbpwent(vp);
- printf("%s: Added user %s.\n", prog_name, user_name);
- exit(0);
- }
- } else {
- /* the entry already existed */
- add_user = False;
- }
-
- /*
- * We are root - just write the new password
- * and the valid last change time.
- */
-
- if(disable_user)
- smb_pwent->acct_ctrl |= ACB_DISABLED;
- else if (enable_user) {
- if(smb_pwent->smb_passwd == NULL) {
- prompt_for_new_password(new_passwd,stdin_passwd_get);
- nt_lm_owf_gen( new_passwd, new_nt_p16, new_p16);
- smb_pwent->smb_passwd = new_p16;
- smb_pwent->smb_nt_passwd = new_nt_p16;
- }
- smb_pwent->acct_ctrl &= ~ACB_DISABLED;
- } else if (set_no_password) {
- smb_pwent->acct_ctrl |= ACB_PWNOTREQ;
- /* This is needed to preserve ACB_PWNOTREQ in mod_smbfilepwd_entry */
- smb_pwent->smb_passwd = NULL;
- smb_pwent->smb_nt_passwd = NULL;
- } else {
- smb_pwent->acct_ctrl &= ~ACB_PWNOTREQ;
- smb_pwent->smb_passwd = new_p16;
- smb_pwent->smb_nt_passwd = new_nt_p16;
- }
-
- if(mod_smbpwd_entry(smb_pwent,True) == False) {
- fprintf(stderr, "%s: Failed to modify entry for user %s.\n",
- prog_name, pwd->pw_name);
- endsmbpwent(vp);
- exit(1);
- }
-
- endsmbpwent(vp);
- if(disable_user)
- printf("User %s disabled.\n", user_name);
- else if(enable_user)
- printf("User %s enabled.\n", user_name);
- else if (set_no_password)
- printf("User %s - set to no password.\n", user_name);
- else
- printf("Password changed for user %s.\n", user_name);
- return 0;
+ /* Get the smb passwd entry for this user */
+ smb_pwent = getsmbpwnam(user_name);
+ if (smb_pwent == NULL) {
+ if(add_user == False) {
+ fprintf(stderr, "Failed to find entry for user %s.\n",
+ pwd->pw_name);
+ endsmbpwent(vp);
+ return False;
+ }
+
+ if (add_new_user(user_name, pwd->pw_uid, trust_account, disable_user,
+ set_no_password, new_p16, new_nt_p16)) {
+ printf("Added user %s.\n", user_name);
+ endsmbpwent(vp);
+ return True;
+ } else {
+ fprintf(stderr, "Failed to add entry for user %s.\n", user_name);
+ endsmbpwent(vp);
+ return False;
+ }
+ } else {
+ /* the entry already existed */
+ add_user = False;
+ }
+
+ /*
+ * We are root - just write the new password
+ * and the valid last change time.
+ */
+
+ if(disable_user) {
+ smb_pwent->acct_ctrl |= ACB_DISABLED;
+ } else if (enable_user) {
+ if(smb_pwent->smb_passwd == NULL) {
+ smb_pwent->smb_passwd = new_p16;
+ smb_pwent->smb_nt_passwd = new_nt_p16;
+ }
+ smb_pwent->acct_ctrl &= ~ACB_DISABLED;
+ } else if (set_no_password) {
+ smb_pwent->acct_ctrl |= ACB_PWNOTREQ;
+ /* This is needed to preserve ACB_PWNOTREQ in mod_smbfilepwd_entry */
+ smb_pwent->smb_passwd = NULL;
+ smb_pwent->smb_nt_passwd = NULL;
+ } else {
+ smb_pwent->acct_ctrl &= ~ACB_PWNOTREQ;
+ smb_pwent->smb_passwd = new_p16;
+ smb_pwent->smb_nt_passwd = new_nt_p16;
+ }
+
+ if(mod_smbpwd_entry(smb_pwent,True) == False) {
+ fprintf(stderr, "Failed to modify entry for user %s.\n",
+ pwd->pw_name);
+ endsmbpwent(vp);
+ return False;
+ }
+
+ endsmbpwent(vp);
+
+ return True;
+}
+
+
+/*************************************************************
+change a password either locally or remotely
+*************************************************************/
+static BOOL password_change(const char *remote_machine, char *user_name,
+ char *old_passwd, char *new_passwd,
+ BOOL add_user, BOOL enable_user,
+ BOOL disable_user, BOOL set_no_password,
+ BOOL trust_account)
+{
+ if (remote_machine != NULL) {
+ if (add_user || enable_user || disable_user || set_no_password || trust_account) {
+ /* these things can't be done remotely yet */
+ return False;
+ }
+ return remote_password_change(remote_machine, user_name, old_passwd, new_passwd);
+ }
+
+ return local_password_change(user_name, trust_account, add_user, enable_user,
+ disable_user, set_no_password, new_passwd);
+}
+
+
+/*************************************************************
+handle password changing for root
+*************************************************************/
+static int process_root(int argc, char *argv[])
+{
+ struct passwd *pwd;
+ int ch;
+ BOOL joining_domain = False;
+ BOOL trust_account = False;
+ BOOL add_user = False;
+ BOOL disable_user = False;
+ BOOL enable_user = False;
+ BOOL set_no_password = False;
+ BOOL stdin_passwd_get = False;
+ char *user_name = NULL;
+ char *new_domain = NULL;
+ char *new_passwd = NULL;
+ char *old_passwd = NULL;
+ char *remote_machine = NULL;
+
+ while ((ch = getopt(argc, argv, "adehmnj:r:sR:D:U:")) != EOF) {
+ switch(ch) {
+ case 'a':
+ add_user = True;
+ break;
+ case 'd':
+ disable_user = True;
+ new_passwd = "XXXXXX";
+ break;
+ case 'e':
+ enable_user = True;
+ break;
+ case 'D':
+ DEBUGLEVEL = atoi(optarg);
+ break;
+ case 'n':
+ set_no_password = True;
+ new_passwd = "NO PASSWORD";
+ 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 'R':
+ lp_set_name_resolve_order(optarg);
+ break;
+ case 'm':
+ trust_account = True;
+ break;
+ case 'j':
+ new_domain = optarg;
+ strupper(new_domain);
+ joining_domain = True;
+ break;
+ case 'U':
+ user_name = optarg;
+ break;
+ default:
+ usage();
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+
+ /*
+ * Ensure add_user and either remote machine or join domain are
+ * not both set.
+ */
+ if(add_user && ((remote_machine != NULL) || joining_domain)) {
+ usage();
+ }
+
+ if(joining_domain) {
+ if (argc != 0) usage();
+ return join_domain(new_domain, remote_machine);
+ }
+
+ /*
+ * Deal with root - can add a user, but only locally.
+ */
+
+ switch(argc) {
+ case 0:
+ break;
+ case 1:
+ user_name = argv[0];
+ break;
+ case 2:
+ user_name = argv[0];
+ new_passwd = argv[1];
+ break;
+ default:
+ usage();
+ }
+
+ if (!user_name && (pwd = getpwuid(0))) {
+ user_name = xstrdup(pwd->pw_name);
+ }
+
+ if (!user_name) {
+ fprintf(stderr,"You must specify a username\n");
+ exit(1);
+ }
+
+ if (!remote_machine && !Get_Pwnam(user_name, True)) {
+ fprintf(stderr, "User \"%s\" was not found in system password file.\n",
+ user_name);
+ exit(1);
+ }
+
+ if (user_name[strlen(user_name)-1] == '$') {
+ user_name[strlen(user_name)-1] = 0;
+ }
+
+ if (trust_account) {
+ /* add the $ automatically */
+ static fstring buf;
+
+ if (add_user) {
+ new_passwd = xstrdup(user_name);
+ strlower(new_passwd);
+ }
+
+ slprintf(buf, sizeof(buf)-1, "%s$", user_name);
+ user_name = buf;
+ }
+
+ if (remote_machine != NULL) {
+ old_passwd = get_pass("Old SMB password:",stdin_passwd_get);
+ }
+
+ if (!new_passwd) {
+ new_passwd = prompt_for_new_password(stdin_passwd_get);
+ }
+
+ if (!password_change(remote_machine, user_name, old_passwd, new_passwd,
+ add_user, enable_user, disable_user, set_no_password,
+ trust_account)) {
+ fprintf(stderr,"Failed to change password entry for %s\n", user_name);
+ return 1;
+ }
+
+ if(disable_user) {
+ printf("User %s disabled.\n", user_name);
+ } else if(enable_user) {
+ printf("User %s enabled.\n", user_name);
+ } else if (set_no_password) {
+ printf("User %s - set to no password.\n", user_name);
+ } else {
+ printf("Password changed for user %s\n", user_name);
+ }
+ return 0;
+}
+
+
+/*************************************************************
+handle password changing for non-root
+*************************************************************/
+static int process_nonroot(int argc, char *argv[])
+{
+ struct passwd *pwd = NULL;
+ int 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(argc > 1) {
+ usage();
+ }
+
+ if (argc == 1) {
+ new_passwd = argv[0];
+ }
+
+ if (!user_name) {
+ pwd = getpwuid(getuid());
+ if (pwd) {
+ user_name = xstrdup(pwd->pw_name);
+ } else {
+ fprintf(stderr,"you don't exist - go away\n");
+ exit(1);
+ }
+ }
+
+ /*
+ * A non-root user is always setting a password
+ * via a remote machine (even if that machine is
+ * localhost).
+ */
+ if (remote_machine == NULL) {
+ remote_machine = "127.0.0.1";
+ }
+
+
+ if (remote_machine != NULL) {
+ old_passwd = get_pass("Old SMB password:",stdin_passwd_get);
+ }
+
+ if (!new_passwd) {
+ new_passwd = prompt_for_new_password(stdin_passwd_get);
+ }
+
+ if (!new_passwd) {
+ printf("unable to get new password\n");
+ exit(0);
+ }
+
+ if (!password_change(remote_machine, user_name, old_passwd, new_passwd,
+ False, False, False, False, False)) {
+ fprintf(stderr,"Failed to change password for %s\n", user_name);
+ return 1;
+ }
+
+ printf("Password changed for user %s\n", user_name);
+ return 0;
+}
+
+
+
+/*********************************************************
+ Start here.
+**********************************************************/
+int main(int argc, char **argv)
+{
+ static pstring servicesf = CONFIGFILE;
+
+ TimeInit();
+
+ setup_logging("smbpasswd", True);
+
+ charset_initialise();
+
+ if(!initialize_password_db()) {
+ fprintf(stderr, "Can't setup password database vectors.\n");
+ exit(1);
+ }
+
+ if (!lp_load(servicesf,True,False,False)) {
+ fprintf(stderr, "Can't load %s - run testparm to debug it\n",
+ servicesf);
+ exit(1);
+ }
+
+ if(!get_myname(myhostname,NULL)) {
+ fprintf(stderr, "unable to get my hostname.\n");
+ exit(1);
+ }
+
+ /*
+ * Set the machine NETBIOS name if not already
+ * set from the config file.
+ */
+
+ if (!*global_myname) {
+ char *p;
+ fstrcpy(global_myname, myhostname);
+ p = strchr(global_myname, '.' );
+ if (p) *p = 0;
+ }
+ strupper(global_myname);
+
+ codepage_initialise(lp_client_code_page());
+
+ /* Check the effective uid - make sure we are not setuid */
+ if ((geteuid() == (uid_t)0) && (getuid() != (uid_t)0)) {
+ fprintf(stderr, "smbpasswd must *NOT* be setuid root.\n");
+ exit(1);
+ }
+
+ if (getuid() == 0) {
+ return process_root(argc, argv);
+ }
+
+ return process_nonroot(argc, argv);
}