summaryrefslogtreecommitdiff
path: root/source3/passdb
diff options
context:
space:
mode:
authorLuke Leighton <lkcl@samba.org>1997-11-06 23:03:58 +0000
committerLuke Leighton <lkcl@samba.org>1997-11-06 23:03:58 +0000
commitbd529d7a83c35be233baca09bc79aa911ad443ce (patch)
treef6187ae5506640e8658998bb5b8cde68f6ec5530 /source3/passdb
parentec35f1c1cc363b84867fea49f6b2b5e3c0b9b889 (diff)
downloadsamba-bd529d7a83c35be233baca09bc79aa911ad443ce.tar.gz
samba-bd529d7a83c35be233baca09bc79aa911ad443ce.tar.bz2
samba-bd529d7a83c35be233baca09bc79aa911ad443ce.zip
following a cvs error, i am rewriting this monster-commit. with bad grace.
Modified Files: --------------- Makefile: adding extra files ipc.c : send_trans_reply() - alignment issue. this makes the alignment the same as that in NT. this should be looked at by people who understand the SMB stuff better than i. api_fd_commands[] - added samr and wkssvc pipes. loadparm.c : lp_domain_controller() changed to mean "samba is a domain controller". it's a "yes/no" parameter, now. no, it isn't used _anywhere_. namedbwork.c nameelect.c : if "domain controller = yes" then add SV_TYPE_DOMAIN_CTRL to the host _and_ workgroup announcements. yes, you must do both: nt does. namelogon.c : important NETLOGON bug in SAMLOGON request parsing, which may be the source of some people's problems with logging on to the Samba PDC. password.c : get_smbpwnam() renamed to get_smbpwd_entry(). pipes.c : added samr and wkssvc pipes. proto.h : usual. can we actually _remove_ proto.h from the cvs tree, and have it as one of the Makefile dependencies, or something? reply.c : get_smbpwnam() renamed to get_smbpwd_entry() - also changed response error code when logging in from a WORKSTATION$ account. yes, paul is right: we need to know when to return the right error code, and why. server.c : added call to reset_chain_pnum(). #ifdef NTDOMAIN added call to init_lsa_policy_hnd() #endif. jeremy, you'd be proud: i did a compile without NTDOMAIN, and caught a link error for this function. smb.h : defines and structures for samr and wkssvc pipes. smbpass.c : modified get_smbpwnam() to get_smbpwd_entry() and it now takes two arguments. one for the name; if this is null, it looks up by smb_userid instead. oh, by the way, smb_userids are actually domain relative ids (RIDs). concatenate a RID with the domain SID, and you have an internet globally unique way of identifying a user. we're using RIDs in the wrong way.... added mod_smbpwnam() function. this was based on code in smbpasswd.c rpc_pipes/lsaparse.c : added enum trusted domain parsing. this is incomplete: i need a packet trace to write it properly. rpc_pipes/pipe_hnd.c : added reset_chain_pnum() function. rpc_pipes/pipenetlog.c : get_smbpwnam() function renamed to get_smbpwd_entry(). arcfour() issues. removed capability of get_md4pw() function to automatically add workstation accounts. this should either be done using smbpasswd -add MACHINE$, or by using \PIPE\samr. rpc_pipes/pipe_util.c : create_pol_hnd() - creates a unique LSA Policy Handle. overkill function: uses a 64 bit sequence number; current unix time and the smbd pid. rpc_pipes/smbparse.c : arcfour() issues. smb_io_unistr2() should advance by uni_str_len not uni_max_len. smb_io_smb_hdr_rb() - request bind uses uint16 for the context id, and uint8 for the num_syntaxes. oops, i put these both as uint32s. Added Files: ------------ rpc_pipes/lsa_hnd.c : on the samr pipe, allocate and associate an LSA Policy Handle with a SID. you receive queries with the LSA Policy Handle, and have to turn this back into a SID in order to answer the query... rpc_pipes/pipesamr.c rpc_pipes/samrparse.c \PIPE\samr processing. samr i presume is the SAM Replication pipe. rpc_pipes/pipewkssvc.c rpc_pipes/wksparse.c \PIPE\wkssvc processing. the Workstation Service pipe? holy cow. (This used to be commit 1bd084b3e690eb26a1006d616075e53d711ecd2f)
Diffstat (limited to 'source3/passdb')
-rw-r--r--source3/passdb/smbpass.c442
1 files changed, 401 insertions, 41 deletions
diff --git a/source3/passdb/smbpass.c b/source3/passdb/smbpass.c
index daa1064750..2c533f16f9 100644
--- a/source3/passdb/smbpass.c
+++ b/source3/passdb/smbpass.c
@@ -103,10 +103,11 @@ static int gethexpwd(char *p, char *pwd)
return (True);
}
-/*
- * Routine to search the smbpasswd file for an entry matching the username.
- */
-struct smb_passwd *get_smbpwnam(char *name)
+/*************************************************************************
+ Routine to search the smbpasswd file for an entry matching the username
+ or user id. if the name is NULL, then the smb_uid is used instead.
+ *************************************************************************/
+struct smb_passwd *get_smbpwd_entry(char *name, int smb_userid)
{
/* Static buffers we will return. */
static struct smb_passwd pw_buf;
@@ -127,19 +128,28 @@ struct smb_passwd *get_smbpwnam(char *name)
DEBUG(0, ("No SMB password file set\n"));
return (NULL);
}
- DEBUG(10, ("get_smbpwnam: opening file %s\n", pfile));
+ DEBUG(10, ("get_smbpwd_entry: opening file %s\n", pfile));
+
+ if (name != NULL)
+ {
+ DEBUG(10, ("get_smbpwd_entry: search by name: %s\n", name));
+ }
+ else
+ {
+ DEBUG(10, ("get_smbpwd_entry: search by smb_userid: %x\n", smb_userid));
+ }
fp = fopen(pfile, "r");
if (fp == NULL) {
- DEBUG(0, ("get_smbpwnam: unable to open file %s\n", pfile));
+ DEBUG(0, ("get_smbpwd_entry: unable to open file %s\n", pfile));
return NULL;
}
/* Set a 16k buffer to do more efficient reads */
setvbuf(fp, readbuf, _IOFBF, sizeof(readbuf));
if ((lockfd = pw_file_lock(pfile, F_RDLCK, 5)) < 0) {
- DEBUG(0, ("get_smbpwnam: unable to lock file %s\n", pfile));
+ DEBUG(0, ("get_smbpwd_entry: unable to lock file %s\n", pfile));
fclose(fp);
return NULL;
}
@@ -175,10 +185,10 @@ struct smb_passwd *get_smbpwnam(char *name)
linebuf[linebuf_len - 1] = '\0';
#ifdef DEBUG_PASSWORD
- DEBUG(100, ("get_smbpwnam: got line |%s|\n", linebuf));
+ DEBUG(100, ("get_smbpwd_entry: got line |%s|\n", linebuf));
#endif
if ((linebuf[0] == 0) && feof(fp)) {
- DEBUG(4, ("get_smbpwnam: end of file reached\n"));
+ DEBUG(4, ("get_smbpwd_entry: end of file reached\n"));
break;
}
/*
@@ -195,12 +205,12 @@ struct smb_passwd *get_smbpwnam(char *name)
*/
if (linebuf[0] == '#' || linebuf[0] == '\0') {
- DEBUG(6, ("get_smbpwnam: skipping comment or blank line\n"));
+ DEBUG(6, ("get_smbpwd_entry: skipping comment or blank line\n"));
continue;
}
p = (unsigned char *) strchr(linebuf, ':');
if (p == NULL) {
- DEBUG(0, ("get_smbpwnam: malformed password entry (no :)\n"));
+ DEBUG(0, ("get_smbpwd_entry: malformed password entry (no :)\n"));
continue;
}
/*
@@ -209,55 +219,89 @@ struct smb_passwd *get_smbpwnam(char *name)
*/
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 */
+ /* get smb uid */
+
p++; /* Go past ':' */
if (!isdigit(*p)) {
- DEBUG(0, ("get_smbpwnam: malformed password entry (uid not number)\n"));
+ DEBUG(0, ("get_smbpwd_entry: malformed password entry (uid not number)\n"));
fclose(fp);
pw_file_unlock(lockfd);
return NULL;
}
+
uidval = atoi((char *) p);
+
while (*p && isdigit(*p))
+ {
p++;
- if (*p != ':') {
- DEBUG(0, ("get_smbpwnam: malformed password entry (no : after uid)\n"));
+ }
+
+ if (*p != ':')
+ {
+ DEBUG(0, ("get_smbpwd_entry: malformed password entry (no : after uid)\n"));
fclose(fp);
pw_file_unlock(lockfd);
return NULL;
}
+
+ if (name != NULL)
+ {
+ /* search is by user name */
+ if (!strequal(user_name, name)) continue;
+ DEBUG(10, ("get_smbpwd_entry: found by name: %s\n", user_name));
+ }
+ else
+ {
+ /* search is by user id */
+ if (uidval != smb_userid) continue;
+ DEBUG(10, ("get_smbpwd_entry: found by smb_userid: %x\n", uidval));
+ }
+
+ /* if we're here, the entry has been found (either by name or uid) */
+
/*
* 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.
*/
+
+ /* skip the ':' */
p++;
- if (*p == '*' || *p == 'X') {
+
+ if (*p == '*' || *p == 'X')
+ {
/* Password deliberately invalid - end here. */
- DEBUG(10, ("get_smbpwnam: entry invalidated for user %s\n", user_name));
+ DEBUG(10, ("get_smbpwd_entry: entry invalidated for user %s\n", user_name));
fclose(fp);
pw_file_unlock(lockfd);
return NULL;
}
- if (linebuf_len < (PTR_DIFF(p, linebuf) + 33)) {
- DEBUG(0, ("get_smbpwnam: malformed password entry (passwd too short)\n"));
+
+ if (linebuf_len < (PTR_DIFF(p, linebuf) + 33))
+ {
+ DEBUG(0, ("get_smbpwd_entry: malformed password entry (passwd too short)\n"));
fclose(fp);
pw_file_unlock(lockfd);
return (False);
}
- if (p[32] != ':') {
- DEBUG(0, ("get_smbpwnam: malformed password entry (no terminating :)\n"));
+
+ if (p[32] != ':')
+ {
+ DEBUG(0, ("get_smbpwd_entry: malformed password entry (no terminating :)\n"));
fclose(fp);
pw_file_unlock(lockfd);
return NULL;
}
- if (!strncasecmp((char *) p, "NO PASSWORD", 11)) {
+
+ if (!strncasecmp((char *) p, "NO PASSWORD", 11))
+ {
pw_buf.smb_passwd = NULL;
- } else {
- if(!gethexpwd((char *)p,(char *)smbpwd)) {
+ }
+ else
+ {
+ if (!gethexpwd((char *)p, (char *)smbpwd))
+ {
DEBUG(0, ("Malformed Lanman password entry (non hex chars)\n"));
fclose(fp);
pw_file_unlock(lockfd);
@@ -265,6 +309,7 @@ struct smb_passwd *get_smbpwnam(char *name)
}
pw_buf.smb_passwd = smbpwd;
}
+
pw_buf.smb_name = user_name;
pw_buf.smb_userid = uidval;
pw_buf.smb_nt_passwd = NULL;
@@ -282,7 +327,7 @@ struct smb_passwd *get_smbpwnam(char *name)
fclose(fp);
pw_file_unlock(lockfd);
- DEBUG(5, ("get_smbpwname: returning passwd entry for user %s, uid %d\n",
+ DEBUG(5, ("get_smbpwd_entrye: returning passwd entry for user %s, uid %d\n",
user_name, uidval));
return &pw_buf;
}
@@ -291,10 +336,11 @@ struct smb_passwd *get_smbpwnam(char *name)
pw_file_unlock(lockfd);
return NULL;
}
+
/*
* Routine to search the smbpasswd file for an entry matching the username.
*/
-BOOL add_smbpwnam(struct smb_passwd* pwd)
+BOOL add_smbpwd_entry(struct smb_passwd* pwd)
{
/* Static buffers we will return. */
static pstring user_name;
@@ -321,13 +367,13 @@ BOOL add_smbpwnam(struct smb_passwd* pwd)
DEBUG(0, ("No SMB password file set\n"));
return False;
}
- DEBUG(10, ("add_smbpwnam: opening file %s\n", pfile));
+ DEBUG(10, ("add_smbpwd_entry: opening file %s\n", pfile));
fp = fopen(pfile, "r+");
if (fp == NULL)
{
- DEBUG(0, ("add_smbpwnam: unable to open file %s\n", pfile));
+ DEBUG(0, ("add_smbpwd_entry: unable to open file %s\n", pfile));
return False;
}
/* Set a 16k buffer to do more efficient reads */
@@ -335,7 +381,7 @@ BOOL add_smbpwnam(struct smb_passwd* pwd)
if ((lockfd = pw_file_lock(pfile, F_RDLCK | F_WRLCK, 5)) < 0)
{
- DEBUG(0, ("add_smbpwnam: unable to lock file %s\n", pfile));
+ DEBUG(0, ("add_smbpwd_entry: unable to lock file %s\n", pfile));
fclose(fp);
return False;
}
@@ -381,12 +427,12 @@ BOOL add_smbpwnam(struct smb_passwd* pwd)
}
#ifdef DEBUG_PASSWORD
- DEBUG(100, ("add_smbpwnam: got line |%s|\n", linebuf));
+ DEBUG(100, ("add_smbpwd_entry: got line |%s|\n", linebuf));
#endif
if ((linebuf[0] == 0) && feof(fp))
{
- DEBUG(4, ("add_smbpwnam: end of file reached\n"));
+ DEBUG(4, ("add_smbpwd_entry: end of file reached\n"));
break;
}
@@ -405,7 +451,7 @@ BOOL add_smbpwnam(struct smb_passwd* pwd)
if (linebuf[0] == '#' || linebuf[0] == '\0')
{
- DEBUG(6, ("add_smbpwnam: skipping comment or blank line\n"));
+ DEBUG(6, ("add_smbpwd_entry: skipping comment or blank line\n"));
continue;
}
@@ -413,7 +459,7 @@ BOOL add_smbpwnam(struct smb_passwd* pwd)
if (p == NULL)
{
- DEBUG(0, ("add_smbpwnam: malformed password entry (no :)\n"));
+ DEBUG(0, ("add_smbpwd_entry: malformed password entry (no :)\n"));
continue;
}
@@ -425,7 +471,7 @@ BOOL add_smbpwnam(struct smb_passwd* pwd)
user_name[PTR_DIFF(p, linebuf)] = '\0';
if (strequal(user_name, pwd->smb_name))
{
- DEBUG(6, ("add_smbpwnam: entry already exists\n"));
+ DEBUG(6, ("add_smbpwd_entry: entry already exists\n"));
return False;
}
}
@@ -440,7 +486,7 @@ BOOL add_smbpwnam(struct smb_passwd* pwd)
if((offpos = lseek(fd, 0, SEEK_END)) == -1)
{
- DEBUG(0, ("add_smbpwnam(lseek): Failed to add entry for user %s to file %s. \
+ DEBUG(0, ("add_smbpwd_entry(lseek): Failed to add entry for user %s to file %s. \
Error was %s\n", pwd->smb_name, pfile, strerror(errno)));
fclose(fp);
@@ -452,7 +498,7 @@ Error was %s\n", pwd->smb_name, pfile, strerror(errno)));
if((new_entry = (char *)malloc( new_entry_length )) == 0)
{
- DEBUG(0, ("add_smbpwnam(malloc): Failed to add entry for user %s to file %s. \
+ DEBUG(0, ("add_smbpwd_entry(malloc): Failed to add entry for user %s to file %s. \
Error was %s\n",
pwd->smb_name, pfile, strerror(errno)));
@@ -482,19 +528,19 @@ Error was %s\n",
sprintf(p,"\n");
#ifdef DEBUG_PASSWORD
- DEBUG(100, ("add_smbpwnam(%d): new_entry_len %d entry_len %d made line |%s|\n",
+ DEBUG(100, ("add_smbpwd_entry(%d): new_entry_len %d entry_len %d made line |%s|\n",
fd, new_entry_length, strlen(new_entry), new_entry));
#endif
if ((wr_len = write(fd, new_entry, strlen(new_entry))) != strlen(new_entry))
{
- DEBUG(0, ("add_smbpwnam(write): %d Failed to add entry for user %s to file %s. \
+ DEBUG(0, ("add_smbpwd_entry(write): %d Failed to add entry for user %s to file %s. \
Error was %s\n", wr_len, pwd->smb_name, pfile, strerror(errno)));
/* Remove the entry we just wrote. */
if(ftruncate(fd, offpos) == -1)
{
- DEBUG(0, ("add_smbpwnam: ERROR failed to ftruncate file %s. \
+ DEBUG(0, ("add_smbpwd_entry: ERROR failed to ftruncate file %s. \
Error was %s. Password file may be corrupt ! Please examine by hand !\n",
pwd->smb_name, strerror(errno)));
}
@@ -508,3 +554,317 @@ Error was %s. Password file may be corrupt ! Please examine by hand !\n",
pw_file_unlock(lockfd);
return True;
}
+/*
+ * Routine to search the smbpasswd file for an entry matching the username.
+ * and then modify its password entry
+ */
+BOOL mod_smbpwd_entry(struct smb_passwd* pwd)
+{
+ /* Static buffers we will return. */
+ static pstring user_name;
+
+ char linebuf[256];
+ char readbuf[16 * 1024];
+ unsigned char c;
+ char ascii_p16[66];
+ unsigned char *p;
+ long linebuf_len;
+ FILE *fp;
+ int lockfd;
+ char *pfile = lp_smb_passwd_file();
+
+ BOOL found_entry = True;
+ long pwd_seekpos = 0;
+
+ int i;
+ int wr_len;
+ int fd;
+
+ if (!*pfile)
+ {
+ DEBUG(0, ("No SMB password file set\n"));
+ return False;
+ }
+ DEBUG(10, ("add_smbpwd_entry: opening file %s\n", pfile));
+
+ fp = fopen(pfile, "r+");
+
+ if (fp == NULL)
+ {
+ DEBUG(0, ("add_smbpwd_entry: unable to open file %s\n", pfile));
+ return False;
+ }
+ /* Set a 16k buffer to do more efficient reads */
+ setvbuf(fp, readbuf, _IOFBF, sizeof(readbuf));
+
+ if ((lockfd = pw_file_lock(pfile, F_RDLCK | F_WRLCK, 5)) < 0)
+ {
+ DEBUG(0, ("add_smbpwd_entry: unable to lock file %s\n", pfile));
+ fclose(fp);
+ return False;
+ }
+ /* make sure it is only rw by the owner */
+ chmod(pfile, 0600);
+
+ /* We have a write lock on the file. */
+ /*
+ * Scan the file, a line at a time and check if the name matches.
+ */
+ while (!feof(fp))
+ {
+ pwd_seekpos = ftell(fp);
+
+ linebuf[0] = '\0';
+
+ fgets(linebuf, 256, fp);
+ if (ferror(fp))
+ {
+ fclose(fp);
+ pw_file_unlock(lockfd);
+ return False;
+ }
+
+ /*
+ * 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';
+ }
+
+#ifdef DEBUG_PASSWORD
+ DEBUG(100, ("add_smbpwd_entry: got line |%s|\n", linebuf));
+#endif
+
+ if ((linebuf[0] == 0) && feof(fp))
+ {
+ DEBUG(4, ("add_smbpwd_entry: end of file reached\n"));
+ 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')
+ {
+ DEBUG(6, ("add_smbpwd_entry: skipping comment or blank line\n"));
+ continue;
+ }
+
+ p = (unsigned char *) strchr(linebuf, ':');
+
+ if (p == NULL)
+ {
+ DEBUG(0, ("add_smbpwd_entry: malformed password entry (no :)\n"));
+ 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, pwd->smb_name))
+ {
+ DEBUG(6, ("add_smbpwd_entry: entry already exists\n"));
+ found_entry = True;
+ break;
+ }
+
+ /* User name matches - get uid and password */
+ p++; /* Go past ':' */
+
+ if (!isdigit(*p))
+ {
+ DEBUG(0, ("mod_smbpwd_entry: malformed password entry (uid not number)\n"));
+ fclose(fp);
+ pw_file_unlock(lockfd);
+ return False;
+ }
+
+ while (*p && isdigit(*p))
+ p++;
+ if (*p != ':')
+ {
+ DEBUG(0, ("mod_smbpwd_entry: malformed password entry (no : after uid)\n"));
+ fclose(fp);
+ pw_file_unlock(lockfd);
+ 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++;
+
+ /* record exact password position */
+ pwd_seekpos += PTR_DIFF(p, linebuf);
+
+ if (*p == '*' || *p == 'X')
+ {
+ /* Password deliberately invalid - end here. */
+ DEBUG(10, ("get_smbpwd_entry: entry invalidated for user %s\n", user_name));
+ fclose(fp);
+ pw_file_unlock(lockfd);
+ return False;
+ }
+
+ if (linebuf_len < (PTR_DIFF(p, linebuf) + 33))
+ {
+ DEBUG(0, ("mod_smbpwd_entry: malformed password entry (passwd too short)\n"));
+ fclose(fp);
+ pw_file_unlock(lockfd);
+ return (False);
+ }
+
+ if (p[32] != ':')
+ {
+ DEBUG(0, ("mod_smbpwd_entry: malformed password entry (no terminating :)\n"));
+ fclose(fp);
+ pw_file_unlock(lockfd);
+ return False;
+ }
+
+ if (*p == '*' || *p == 'X')
+ {
+ fclose(fp);
+ pw_file_unlock(lockfd);
+ return False;
+ }
+ if (!strncasecmp((char *) p, "NO PASSWORD", 11))
+ {
+ fclose(fp);
+ pw_file_unlock(lockfd);
+ return False;
+ }
+
+ /* 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))
+ {
+ DEBUG(0, ("mod_smbpwd_entry: malformed password entry (passwd too short)\n"));
+ fclose(fp);
+ pw_file_unlock(lockfd);
+ return (False);
+ }
+
+ if (p[32] != ':')
+ {
+ DEBUG(0, ("mod_smbpwd_entry: malformed password entry (no terminating :)\n"));
+ fclose(fp);
+ pw_file_unlock(lockfd);
+ return False;
+ }
+
+ if (*p == '*' || *p == 'X')
+ {
+ fclose(fp);
+ pw_file_unlock(lockfd);
+ return False;
+ }
+
+ /* whew. entry is correctly formed. */
+ break;
+ }
+
+ /*
+ * Do an atomic write into the file at the position defined by
+ * seekpos.
+ */
+
+ /* The mod user write needs to be atomic - so get the fd from
+ the fp and do a raw write() call.
+ */
+
+ fd = fileno(fp);
+
+ if (lseek(fd, pwd_seekpos - 1, SEEK_SET) != pwd_seekpos - 1)
+ {
+ DEBUG(1, ("mod_smbpwd_entry: seek fail on file %s.\n", pfile));
+ fclose(fp);
+ pw_file_unlock(lockfd);
+ return False;
+ }
+
+ /* Sanity check - ensure the character is a ':' */
+ if (read(fd, &c, 1) != 1)
+ {
+ DEBUG(1, ("mod_smbpwd_entry: read fail on file %s.\n", pfile));
+ fclose(fp);
+ pw_file_unlock(lockfd);
+ return False;
+ }
+
+ if (c != ':')
+ {
+ DEBUG(1, ("mod_smbpwd_entry: check on passwd file %s failed.\n", pfile));
+ fclose(fp);
+ pw_file_unlock(lockfd);
+ return False;
+ }
+
+ /* Create the 32 byte representation of the new p16 */
+ for (i = 0; i < 16; i++)
+ {
+ sprintf(&ascii_p16[i*2], "%02X", (uchar) pwd->smb_passwd[i]);
+ }
+ if (pwd->smb_nt_passwd != NULL)
+ {
+ /* Add on the NT md4 hash */
+ ascii_p16[32] = ':';
+ for (i = 0; i < 16; i++)
+ {
+ sprintf(&ascii_p16[(i*2)+33], "%02X", (uchar) pwd->smb_nt_passwd[i]);
+ }
+ wr_len = 65;
+ }
+ else
+ {
+ wr_len = 32;
+ }
+
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("mod_smbpwd_entry: "));
+ dump_data(100, ascii_p16, wr_len);
+#endif
+
+ if (write(fd, ascii_p16, wr_len) != wr_len)
+ {
+ DEBUG(1, ("mod_smbpwd_entry: write failed in passwd file %s\n", pfile));
+ fclose(fp);
+ pw_file_unlock(lockfd);
+ return False;
+ }
+
+ fclose(fp);
+ pw_file_unlock(lockfd);
+ return True;
+}