summaryrefslogtreecommitdiff
path: root/source3/utils
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>1998-04-18 02:00:39 +0000
committerJeremy Allison <jra@samba.org>1998-04-18 02:00:39 +0000
commit6733e2b36e00ccbe8df363651ecc98ba42d53cee (patch)
tree8c9d81eb8feed60cf88491c12addaad81cbcd8e0 /source3/utils
parentf9a96f060bdc8d045748b5f7e31d177e43e8810a (diff)
downloadsamba-6733e2b36e00ccbe8df363651ecc98ba42d53cee.tar.gz
samba-6733e2b36e00ccbe8df363651ecc98ba42d53cee.tar.bz2
samba-6733e2b36e00ccbe8df363651ecc98ba42d53cee.zip
includes.h: Added John's redhat fix for QSORT_CAST.
smbpass.c: Added lock depth code so calls to pw_file_lock() can be nested. Fixed codedump problems in add_smbpwd_entry(). smbpasswd.c: Removed all the code that manipulated the password file directly. Now *all* smbpasswd file changes are done through the interfaces defined in smbpass.c This should make the life of people adding alternate backend databases *much* easier. lib/rpc/server/srv_netlog.c: Removed debug messages used to debug machine password changing. Jeremy. (This used to be commit c9f61be08f3691a6421734d8b026a295d9cbd6ba)
Diffstat (limited to 'source3/utils')
-rw-r--r--source3/utils/smbpasswd.c585
1 files changed, 56 insertions, 529 deletions
diff --git a/source3/utils/smbpasswd.c b/source3/utils/smbpasswd.c
index 97a38977dc..cf9cd54ef3 100644
--- a/source3/utils/smbpasswd.c
+++ b/source3/utils/smbpasswd.c
@@ -73,341 +73,6 @@ char *get_error_message(struct cli_state *cli)
return error_message;
}
-/******************************************************
- Convert a hex password.
-*******************************************************/
-
-static int gethexpwd(char *p, char *pwd)
-{
- int i;
- unsigned char lonybble, hinybble;
- char *hexchars = "0123456789ABCDEF";
- char *p1, *p2;
- for (i = 0; i < 32; i += 2) {
- hinybble = toupper(p[i]);
- lonybble = toupper(p[i + 1]);
-
- p1 = strchr(hexchars, hinybble);
- p2 = strchr(hexchars, lonybble);
- if (!p1 || !p2)
- return (False);
-
- hinybble = PTR_DIFF(p1, hexchars);
- lonybble = PTR_DIFF(p2, hexchars);
-
- pwd[i / 2] = (hinybble << 4) | lonybble;
- }
- return (True);
-}
-
-/******************************************************
- Find a password entry by name.
-*******************************************************/
-
-static struct smb_passwd *
-_my_get_smbpwnam(FILE * fp, char *name, BOOL * valid_old_pwd,
- BOOL *got_valid_nt_entry, BOOL *got_valid_last_change_time, long *pwd_seekpos)
-{
- /* Static buffers we will return. */
- static struct smb_passwd pw_buf;
- static pstring user_name;
- static unsigned char smbpwd[16];
- static unsigned char smbntpwd[16];
-
- char linebuf[256];
- unsigned char c;
- unsigned char *p;
- long uidval;
- long linebuf_len;
-
- pw_buf.acct_ctrl = ACB_NORMAL;
- *got_valid_last_change_time = False;
- *got_valid_nt_entry = False;
- *valid_old_pwd = False;
-
- /*
- * Scan the file, a line at a time and check if the name matches.
- */
- while (!feof(fp)) {
- linebuf[0] = '\0';
- *pwd_seekpos = ftell(fp);
-
- fgets(linebuf, 256, fp);
- if (ferror(fp))
- return NULL;
-
- /*
- * Check if the string is terminated with a newline - if not
- * then we must keep reading and discard until we get one.
- */
- linebuf_len = strlen(linebuf);
- if (linebuf[linebuf_len - 1] != '\n') {
- c = '\0';
- while (!ferror(fp) && !feof(fp)) {
- c = fgetc(fp);
- if (c == '\n')
- break;
- }
- } else
- linebuf[linebuf_len - 1] = '\0';
-
- if ((linebuf[0] == 0) && feof(fp))
- break;
- /*
- * The line we have should be of the form :-
- *
- * username:uid:[32hex bytes]:....other flags presently
- * ignored....
- *
- * or,
- *
- * username:uid:[32hex bytes]:[32hex bytes]:....ignored....
- *
- * if Windows NT compatible passwords are also present.
- */
-
- if (linebuf[0] == '#' || linebuf[0] == '\0')
- continue;
- p = (unsigned char *) strchr(linebuf, ':');
- if (p == NULL)
- continue;
- /*
- * As 256 is shorter than a pstring we don't need to check
- * length here - if this ever changes....
- */
- strncpy(user_name, linebuf, PTR_DIFF(p, linebuf));
- user_name[PTR_DIFF(p, linebuf)] = '\0';
- if (!strequal(user_name, name))
- continue;
-
- /* User name matches - get uid and password */
- p++; /* Go past ':' */
- if (!isdigit(*p))
- return (False);
-
- uidval = atoi((char *) p);
- while (*p && isdigit(*p))
- p++;
-
- if (*p != ':')
- return (False);
-
- /*
- * Now get the password value - this should be 32 hex digits
- * which are the ascii representations of a 16 byte string.
- * Get two at a time and put them into the password.
- */
- p++;
- *pwd_seekpos += PTR_DIFF(p, linebuf); /* Save exact position
- * of passwd in file -
- * this is used by
- * smbpasswd.c */
- if (*p == '*' || *p == 'X') {
- /* Password deliberately invalid - end here. */
- *valid_old_pwd = False;
- *got_valid_nt_entry = False;
- pw_buf.smb_nt_passwd = NULL; /* No NT password (yet)*/
-
- pw_buf.acct_ctrl |= ACB_DISABLED;
-
- /* Now check if the NT compatible password is
- available. */
- p += 33; /* Move to the first character of the line after
- the lanman password. */
- if ((linebuf_len >= (PTR_DIFF(p, linebuf) + 33)) && (p[32] == ':')) {
- /* NT Entry was valid - even if 'X' or '*', can be overwritten */
- *got_valid_nt_entry = True;
- if (*p != '*' && *p != 'X') {
- if (gethexpwd((char *)p,(char *)smbntpwd))
- pw_buf.smb_nt_passwd = smbntpwd;
- }
- }
- pw_buf.smb_name = user_name;
- pw_buf.smb_userid = uidval;
- pw_buf.smb_passwd = NULL; /* No password */
- return (&pw_buf);
- }
- if (linebuf_len < (PTR_DIFF(p, linebuf) + 33))
- return (False);
-
- if (p[32] != ':')
- return (False);
-
- if (!strncasecmp((char *)p, "NO PASSWORD", 11)) {
- pw_buf.smb_passwd = NULL; /* No password */
- pw_buf.acct_ctrl |= ACB_PWNOTREQ;
- } else {
- if(!gethexpwd((char *)p,(char *)smbpwd))
- return False;
- pw_buf.smb_passwd = smbpwd;
- }
-
- pw_buf.smb_name = user_name;
- pw_buf.smb_userid = uidval;
- pw_buf.smb_nt_passwd = NULL;
- *got_valid_nt_entry = False;
- *valid_old_pwd = True;
-
- /* Now check if the NT compatible password is
- available. */
- p += 33; /* Move to the first character of the line after
- the lanman password. */
- if ((linebuf_len >= (PTR_DIFF(p, linebuf) + 33)) && (p[32] == ':')) {
- /* NT Entry was valid - even if 'X' or '*', can be overwritten */
- *got_valid_nt_entry = True;
- if (*p != '*' && *p != 'X') {
- if (gethexpwd((char *)p,(char *)smbntpwd))
- pw_buf.smb_nt_passwd = smbntpwd;
- }
-
- p += 33; /* Move to the first character of the line after
- the NT password. */
- }
-
- /*
- * Check if the account type bits have been encoded after the
- * NT password (in the form [NDHTUWSLXI]).
- */
-
- if (*p == '[') {
- BOOL finished = False;
-
- pw_buf.acct_ctrl = 0;
-
- for(p++;*p && !finished; p++) {
- switch (*p) {
-#if 0
- /*
- * Hmmm. Don't allow these to be set/read independently
- * of the actual password fields. We don't want a mismatch.
- * JRA.
- */
- case 'N':
- /* 'N'o password. */
- pw_buf.acct_ctrl |= ACB_PWNOTREQ;
- break;
- case 'D':
- /* 'D'isabled. */
- pw_buf.acct_ctrl |= ACB_DISABLED;
- break;
-#endif
- case 'H':
- /* 'H'omedir required. */
- pw_buf.acct_ctrl |= ACB_HOMDIRREQ;
- break;
- case 'T':
- /* 'T'emp account. */
- pw_buf.acct_ctrl |= ACB_TEMPDUP;
- break;
- case 'U':
- /* 'U'ser account (normal). */
- pw_buf.acct_ctrl |= ACB_NORMAL;
- break;
- case 'M':
- /* 'M'NS logon user account. What is this ? */
- pw_buf.acct_ctrl |= ACB_MNS;
- break;
- case 'W':
- /* 'W'orkstation account. */
- pw_buf.acct_ctrl |= ACB_WSTRUST;
- break;
- case 'S':
- /* 'S'erver account. */
- pw_buf.acct_ctrl |= ACB_SVRTRUST;
- break;
- case 'L':
- /* 'L'ocked account. */
- pw_buf.acct_ctrl |= ACB_AUTOLOCK;
- break;
- case 'X':
- /* No 'X'piry. */
- pw_buf.acct_ctrl |= ACB_PWNOEXP;
- break;
- case 'I':
- /* 'I'nterdomain trust account. */
- pw_buf.acct_ctrl |= ACB_DOMTRUST;
- break;
-
- case ':':
- case '\n':
- case '\0':
- case ']':
- default:
- finished = True;
- }
- }
-
- /* Must have some account type set. */
- if(pw_buf.acct_ctrl == 0)
- pw_buf.acct_ctrl = ACB_NORMAL;
-
- /* Now try and get the last change time. */
- if(*p == ']')
- p++;
- if(*p == ':') {
- p++;
- if(*p && StrnCaseCmp( p, "LCT-", 4)) {
- int i;
- p += 4;
- for(i = 0; i < 8; i++) {
- if(p[i] == '\0' || !isxdigit(p[i]))
- break;
- }
- if(i == 8) {
- /*
- * p points at 8 characters of hex digits -
- * read into a time_t as the seconds since
- * 1970 that the password was last changed.
- */
- pw_buf.last_change_time = (time_t)strtol(p, NULL, 16);
- *got_valid_last_change_time = True;
- } /* i == 8 */
- } /* *p && StrnCaseCmp() */
- } /* *p == ':' */
-
- } else {
- /* 'Old' style file. Fake up based on user name. */
- /*
- * Currently machine accounts are kept in the same
- * password file as 'normal accounts'. If this changes
- * we will have to fix this code. JRA.
- */
- if(pw_buf.smb_name[strlen(pw_buf.smb_name) - 1] == '$') {
- pw_buf.acct_ctrl &= ~ACB_NORMAL;
- pw_buf.acct_ctrl |= ACB_WSTRUST;
- }
- }
- return &pw_buf;
- }
- return NULL;
-}
-
-/**********************************************************
- Allocate an unused uid in the smbpasswd file to a new
- machine account.
-***********************************************************/
-
-int get_new_machine_uid(void)
-{
- int next_uid_start;
- void *vp;
- struct smb_passwd *smbpw;
-
- if(sizeof(uid_t) == 2)
- next_uid_start = 65533;
-
- if(sizeof(uid_t) == 4)
- next_uid_start = 0x7fffffff;
-
- vp = startsmbpwent(False);
- while((smbpw = getsmbpwent(vp)) != NULL) {
- if((smbpw->acct_ctrl & (ACB_SVRTRUST|ACB_WSTRUST)))
- next_uid_start = MIN(next_uid_start, (smbpw->smb_userid-1));
- }
- endsmbpwent(vp);
- return next_uid_start;
-}
-
/*********************************************************
Print command usage on stderr and die.
**********************************************************/
@@ -434,7 +99,6 @@ int main(int argc, char **argv)
char *prog_name;
int real_uid;
struct passwd *pwd;
- struct passwd machine_account_pwd;
fstring old_passwd;
fstring new_passwd;
uchar new_p16[16];
@@ -442,28 +106,18 @@ int main(int argc, char **argv)
char *p;
struct smb_passwd *smb_pwent;
FILE *fp;
- BOOL valid_old_pwd = False;
- BOOL got_valid_nt_entry = False;
- long seekpos;
- int pwfd;
- pstring ascii_p16;
- char c;
int ch;
- int ret, i, err, writelen;
- int lockfd = -1;
- char *pfile = SMB_PASSWD_FILE;
- char readbuf[16 * 1024];
+ int err;
BOOL is_root = False;
pstring user_name;
- pstring machine_dir_name;
char *remote_machine = NULL;
BOOL add_user = False;
BOOL got_new_pass = False;
- BOOL got_valid_last_change_time = False;
BOOL machine_account = False;
BOOL disable_user = False;
BOOL set_no_password = False;
pstring servicesf = CONFIGFILE;
+ void *vp;
new_passwd[0] = '\0';
user_name[0] = '\0';
@@ -758,26 +412,14 @@ int main(int argc, char **argv)
}
/*
- * Check for a machine account flag - make sure the username ends in
- * a '$' etc....
+ * Check for a machine account.
*/
if(machine_account && !pwd) {
-
- /*
- * Setup the pwd struct to point to known
- * values for a machine account (it doesn't
- * exist in /etc/passwd).
- */
-
- pwd = &machine_account_pwd;
- pwd->pw_name = user_name;
- sprintf(machine_dir_name, "Workstation machine account for %s", user_name);
- pwd->pw_gecos = "";
- pwd->pw_dir = machine_dir_name;
- pwd->pw_shell = "";
- pwd->pw_uid = get_new_machine_uid();
-
+ 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. */
@@ -797,130 +439,64 @@ int main(int argc, char **argv)
E_P16((uchar *) new_passwd, new_p16);
/*
- * Open the smbpaswd file XXXX - we need to parse smb.conf to get the
- * filename
+ * Open the smbpaswd file.
*/
- fp = fopen(pfile, "r+");
- if (!fp && errno == ENOENT) {
- fp = fopen(pfile, "w");
+ vp = startsmbpwent(True);
+ if (!vp && errno == ENOENT) {
+ fp = fopen(lp_smb_passwd_file(), "w");
if (fp) {
fprintf(fp, "# Samba SMB password file\n");
fclose(fp);
- fp = fopen(pfile, "r+");
+ vp = startsmbpwent(True);
}
}
if (!fp) {
err = errno;
fprintf(stderr, "%s: Failed to open password file %s.\n",
- prog_name, pfile);
+ prog_name, lp_smb_passwd_file());
errno = err;
perror(prog_name);
exit(err);
}
- /* Set read buffer to 16k for effiecient reads */
- setvbuf(fp, readbuf, _IOFBF, sizeof(readbuf));
-
- /* make sure it is only rw by the owner */
- chmod(pfile, 0600);
-
- /* Lock the smbpasswd file for write. */
- if ((lockfd = pw_file_lock(fileno(fp), F_WRLCK, 5)) < 0) {
- err = errno;
- fprintf(stderr, "%s: Failed to lock password file %s.\n",
- prog_name, pfile);
- fclose(fp);
- errno = err;
- perror(prog_name);
- exit(err);
- }
-
/* Get the smb passwd entry for this user */
- smb_pwent = _my_get_smbpwnam(fp, user_name, &valid_old_pwd,
- &got_valid_nt_entry, &got_valid_last_change_time, &seekpos);
+ smb_pwent = getsmbpwnam(user_name);
if (smb_pwent == NULL) {
if(add_user == False) {
- fprintf(stderr, "%s: Failed to find entry for user %s in file %s.\n",
- prog_name, pwd->pw_name, pfile);
- fclose(fp);
- pw_file_unlock(lockfd);
+ 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. */
{
- int fd;
- int new_entry_length;
- char *new_entry;
- long offpos;
- uint16 acct_ctrl = (machine_account ? ACB_WSTRUST : ACB_NORMAL);
-
- /* The add user write needs to be atomic - so get the fd from
- the fp and do a raw write() call.
- */
- fd = fileno(fp);
-
- if((offpos = lseek(fd, 0, SEEK_END)) == -1) {
- fprintf(stderr, "%s: Failed to add entry for user %s to file %s. \
-Error was %s\n", prog_name, user_name, pfile, strerror(errno));
- fclose(fp);
- pw_file_unlock(lockfd);
- exit(1);
- }
+ struct smb_passwd new_smb_pwent;
- new_entry_length = strlen(user_name) + 1 + 15 + 1 +
- 32 + 1 + 32 + 1 + sizeof(fstring) +
- 1 + 13 +
- 1 + strlen(pwd->pw_dir) + 1 +
- strlen(pwd->pw_shell) + 1;
- if((new_entry = (char *)malloc( new_entry_length )) == 0) {
- fprintf(stderr, "%s: Failed to add entry for user %s to file %s. \
-Error was %s\n", prog_name, pwd->pw_name, pfile, strerror(errno));
- pw_file_unlock(lockfd);
- fclose(fp);
- exit(1);
- }
+ 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 = (machine_account ? ACB_WSTRUST : ACB_NORMAL);
- sprintf(new_entry, "%s:%u:", pwd->pw_name, (unsigned)pwd->pw_uid);
- p = &new_entry[strlen(new_entry)];
if(disable_user) {
- memcpy(p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 32);
- p += 32;
- *p++ = ':';
- memcpy(p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 32);
+ new_smb_pwent.acct_ctrl |= ACB_DISABLED;
} else if (set_no_password) {
- memcpy(p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 32);
- p += 32;
- *p++ = ':';
- memcpy(p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 32);
+ new_smb_pwent.acct_ctrl |= ACB_PWNOTREQ;
} else {
- for( i = 0; i < 16; i++)
- sprintf(&p[i*2], "%02X", new_p16[i]);
- p += 32;
- *p++ = ':';
- for( i = 0; i < 16; i++)
- sprintf(&p[i*2], "%02X", new_nt_p16[i]);
+ new_smb_pwent.smb_passwd = new_p16;
+ new_smb_pwent.smb_nt_passwd = new_nt_p16;
}
- p += 32;
- *p++ = ':';
- sprintf(p, "%s:TLC-%08X:%s:%s\n", encode_acct_ctrl(acct_ctrl),
- (uint32)time(NULL), pwd->pw_dir, pwd->pw_shell);
- if(write(fd, new_entry, strlen(new_entry)) != strlen(new_entry)) {
- fprintf(stderr, "%s: Failed to add entry for user %s to file %s. \
-Error was %s\n", prog_name, pwd->pw_name, pfile, strerror(errno));
- /* Remove the entry we just wrote. */
- if(ftruncate(fd, offpos) == -1) {
- fprintf(stderr, "%s: ERROR failed to ftruncate file %s. \
-Error was %s. Password file may be corrupt ! Please examine by hand !\n",
- prog_name, pwd->pw_name, strerror(errno));
- }
- pw_file_unlock(lockfd);
- fclose(fp);
+
+ 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);
}
- pw_file_unlock(lockfd);
- fclose(fp);
+ endsmbpwent(vp);
+ printf("%s: Added user %s.\n", prog_name, user_name);
exit(0);
}
} else {
@@ -933,84 +509,35 @@ Error was %s. Password file may be corrupt ! Please examine by hand !\n",
* and the valid last change time.
*/
- /* Create the 32 byte representation of the new p16 */
if(disable_user) {
- memcpy(ascii_p16, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 32);
+ /*
+ * This currently won't work as it means changing
+ * the length of the record. JRA.
+ */
+ smb_pwent->acct_ctrl |= ACB_DISABLED;
+ smb_pwent->smb_passwd = NULL;
+ smb_pwent->smb_nt_passwd = NULL;
} else if (set_no_password) {
- memcpy(ascii_p16, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 32);
+ /*
+ * This currently won't work as it means changing
+ * the length of the record. JRA.
+ */
+ smb_pwent->acct_ctrl |= ACB_PWNOTREQ;
+ smb_pwent->smb_passwd = NULL;
+ smb_pwent->smb_nt_passwd = NULL;
} else {
- for (i = 0; i < 16; i++) {
- sprintf(&ascii_p16[i * 2], "%02X", (uchar) new_p16[i]);
- }
- }
- if(got_valid_nt_entry) {
- /* Add on the NT md4 hash */
- ascii_p16[32] = ':';
- if(disable_user) {
- memcpy(&ascii_p16[33], "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 32);
- } else if (set_no_password) {
- memcpy(&ascii_p16[33], "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 32);
- } else {
- for (i = 0; i < 16; i++) {
- sprintf(&ascii_p16[(i * 2)+33], "%02X", (uchar) new_nt_p16[i]);
- }
- }
- }
- ascii_p16[65] = ':';
- ascii_p16[66] = '\0';
- if(got_valid_last_change_time) {
- strcpy(&ascii_p16[66], encode_acct_ctrl(smb_pwent->acct_ctrl));
- sprintf(&ascii_p16[strlen(ascii_p16)], ":TLC-%08X", (uint32)time(NULL));
+ smb_pwent->smb_passwd = new_p16;
+ smb_pwent->smb_nt_passwd = new_nt_p16;
}
- /*
- * Do an atomic write into the file at the position defined by
- * seekpos.
- */
- pwfd = fileno(fp);
- ret = lseek(pwfd, seekpos - 1, SEEK_SET);
- if (ret != seekpos - 1) {
- err = errno;
- fprintf(stderr, "%s: seek fail on file %s.\n",
- prog_name, pfile);
- errno = err;
- perror(prog_name);
- pw_file_unlock(lockfd);
- fclose(fp);
+ if(mod_smbpwd_entry(smb_pwent) == False) {
+ fprintf(stderr, "%s: Failed to modify entry for user %s.\n",
+ prog_name, pwd->pw_name);
+ endsmbpwent(vp);
exit(1);
}
- /* Sanity check - ensure the character is a ':' */
- if (read(pwfd, &c, 1) != 1) {
- err = errno;
- fprintf(stderr, "%s: read fail on file %s.\n",
- prog_name, pfile);
- errno = err;
- perror(prog_name);
- pw_file_unlock(lockfd);
- fclose(fp);
- exit(1);
- }
- if (c != ':') {
- fprintf(stderr, "%s: sanity check on passwd file %s failed.\n",
- prog_name, pfile);
- pw_file_unlock(lockfd);
- fclose(fp);
- exit(1);
- }
- writelen = (got_valid_nt_entry) ?
- ( got_valid_last_change_time ? strlen(ascii_p16) : 65) : 32;
- if (write(pwfd, ascii_p16, writelen) != writelen) {
- err = errno;
- fprintf(stderr, "%s: write fail in file %s.\n",
- prog_name, pfile);
- errno = err;
- perror(prog_name);
- pw_file_unlock(lockfd);
- fclose(fp);
- exit(err);
- }
- pw_file_unlock(lockfd);
- fclose(fp);
+
+ endsmbpwent(vp);
if(disable_user)
printf("User %s disabled.\n", user_name);
else if (set_no_password)