2 * Unix SMB/Netbios implementation. Version 1.9. SMB parameters and setup
3 * Copyright (C) Andrew Tridgell 1992-1998 Modified by Jeremy Allison 1995.
5 * This program is free software; you can redistribute it and/or modify it under
6 * the terms of the GNU General Public License as published by the Free
7 * Software Foundation; either version 2 of the License, or (at your option)
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * You should have received a copy of the GNU General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc., 675
17 * Mass Ave, Cambridge, MA 02139, USA.
24 extern int DEBUGLEVEL;
25 extern pstring samlogon_user;
26 extern BOOL sam_logon_in_ssb;
28 static char s_readbuf[16 * 1024];
30 /***************************************************************
31 Start to enumerate the smbpasswd list. Returns a void pointer
32 to ensure no modification outside this module.
34 do not call this function directly. use passdb.c instead.
36 ****************************************************************/
37 void *startsmbpwent(BOOL update)
40 char *pfile = lp_smb_passwd_file();
43 DEBUG(0, ("startsmbpwent: No SMB password file set\n"));
46 DEBUG(10, ("startsmbpwent: opening file %s\n", pfile));
48 fp = fopen(pfile, update ? "r+b" : "rb");
51 DEBUG(0, ("startsmbpwent: unable to open file %s\n", pfile));
55 /* Set a 16k buffer to do more efficient reads */
56 setvbuf(fp, s_readbuf, _IOFBF, sizeof(s_readbuf));
58 if (!pw_file_lock(fileno(fp), (update ? F_WRLCK : F_RDLCK), 5, &pw_file_lock_depth))
60 DEBUG(0, ("startsmbpwent: unable to lock file %s\n", pfile));
65 /* Make sure it is only rw by the owner */
68 /* We have a lock on the file. */
72 /***************************************************************
73 End enumeration of the smbpasswd list.
74 ****************************************************************/
75 void endsmbpwent(void *vp)
77 FILE *fp = (FILE *)vp;
79 pw_file_unlock(fileno(fp), &pw_file_lock_depth);
81 DEBUG(7, ("endsmbpwent: closed password file.\n"));
84 /*************************************************************************
85 Routine to return the next entry in the smbpasswd list.
86 this function is a nice, messy combination of reading:
88 - the unix password database
89 - smb.conf options (not done at present).
91 do not call this function directly. use passdb.c instead.
93 *************************************************************************/
94 struct sam_passwd *getsmb21pwent(void *vp)
96 struct smb_passwd *pw_buf = getsmbpwent(vp);
97 static struct sam_passwd user;
98 struct passwd *pwfile;
100 static pstring full_name;
101 static pstring home_dir;
102 static pstring home_drive;
103 static pstring logon_script;
104 static pstring profile_path;
105 static pstring acct_desc;
106 static pstring workstations;
108 if (pw_buf == NULL) return NULL;
110 pwfile = getpwnam(pw_buf->smb_name);
111 if (pwfile == NULL) return NULL;
113 bzero(&user, sizeof(user));
115 pstrcpy(samlogon_user, pw_buf->smb_name);
117 if (samlogon_user[strlen(samlogon_user)-1] != '$')
119 /* XXXX hack to get standard_sub_basic() to use sam logon username */
120 /* possibly a better way would be to do a become_user() call */
121 sam_logon_in_ssb = True;
123 user.smb_userid = pw_buf->smb_userid;
124 user.smb_grpid = pwfile->pw_gid;
126 user.user_rid = pdb_uid_to_user_rid (user.smb_userid);
127 user.group_rid = pdb_gid_to_group_rid(user.smb_grpid );
129 pstrcpy(full_name , pwfile->pw_gecos );
130 pstrcpy(logon_script , lp_logon_script ());
131 pstrcpy(profile_path , lp_logon_path ());
132 pstrcpy(home_drive , lp_logon_drive ());
133 pstrcpy(home_dir , lp_logon_home ());
134 pstrcpy(acct_desc , "");
135 pstrcpy(workstations , "");
137 sam_logon_in_ssb = False;
141 user.smb_userid = pw_buf->smb_userid;
142 user.smb_grpid = pwfile->pw_gid;
144 user.user_rid = uid_to_user_rid (user.smb_userid);
145 user.group_rid = DOMAIN_GROUP_RID_USERS; /* lkclXXXX this is OBSERVED behaviour by NT PDCs, enforced here. */
147 pstrcpy(full_name , "");
148 pstrcpy(logon_script , "");
149 pstrcpy(profile_path , "");
150 pstrcpy(home_drive , "");
151 pstrcpy(home_dir , "");
152 pstrcpy(acct_desc , "");
153 pstrcpy(workstations , "");
156 user.logon_time = (time_t)-1;
157 user.logoff_time = (time_t)-1;
158 user.kickoff_time = (time_t)-1;
159 user.pass_last_set_time = pw_buf->pass_last_set_time;
160 user.pass_can_change_time = (time_t)-1;
161 user.pass_must_change_time = (time_t)-1;
163 user.smb_name = pw_buf->smb_name;
164 user.full_name = full_name;
165 user.home_dir = home_dir;
166 user.dir_drive = home_drive;
167 user.logon_script = logon_script;
168 user.profile_path = profile_path;
169 user.acct_desc = acct_desc;
170 user.workstations = workstations;
172 user.unknown_str = NULL; /* don't know, yet! */
173 user.munged_dial = NULL; /* "munged" dial-back telephone number */
175 user.smb_nt_passwd = pw_buf->smb_nt_passwd;
176 user.smb_passwd = pw_buf->smb_passwd;
178 user.acct_ctrl = pw_buf->acct_ctrl;
180 user.unknown_3 = 0xffffff; /* don't know */
181 user.logon_divs = 168; /* hours per week */
182 user.hours_len = 21; /* 21 times 8 bits = 168 */
183 memset(user.hours, 0xff, user.hours_len); /* available at all hours */
184 user.unknown_5 = 0x00020000; /* don't know */
185 user.unknown_5 = 0x000004ec; /* don't know */
190 /*************************************************************************
191 Routine to return the next entry in the smbpasswd list.
193 do not call this function directly. use passdb.c instead.
195 *************************************************************************/
196 struct smb_passwd *getsmbpwent(void *vp)
198 /* Static buffers we will return. */
199 static struct smb_passwd pw_buf;
200 static pstring user_name;
201 static unsigned char smbpwd[16];
202 static unsigned char smbntpwd[16];
203 FILE *fp = (FILE *)vp;
211 DEBUG(0,("getsmbpwent: Bad password file pointer.\n"));
215 pw_buf.acct_ctrl = ACB_NORMAL;
216 pw_buf.pass_last_set_time = (time_t)-1;
219 * Scan the file, a line at a time and check if the name matches.
224 fgets(linebuf, 256, fp);
230 * Check if the string is terminated with a newline - if not
231 * then we must keep reading and discard until we get one.
233 linebuf_len = strlen(linebuf);
234 if (linebuf[linebuf_len - 1] != '\n') {
236 while (!ferror(fp) && !feof(fp)) {
242 linebuf[linebuf_len - 1] = '\0';
244 #ifdef DEBUG_PASSWORD
245 DEBUG(100, ("getsmbpwent: got line |%s|\n", linebuf));
247 if ((linebuf[0] == 0) && feof(fp)) {
248 DEBUG(4, ("getsmbpwent: end of file reached\n"));
252 * The line we have should be of the form :-
254 * username:uid:32hex bytes:[Account type]:LCT-12345678....other flags presently
259 * username:uid:32hex bytes:32hex bytes:[Account type]:LCT-12345678....ignored....
261 * if Windows NT compatible passwords are also present.
262 * [Account type] is an ascii encoding of the type of account.
263 * LCT-(8 hex digits) is the time_t value of the last change time.
266 if (linebuf[0] == '#' || linebuf[0] == '\0') {
267 DEBUG(6, ("getsmbpwent: skipping comment or blank line\n"));
270 p = (unsigned char *) strchr(linebuf, ':');
272 DEBUG(0, ("getsmbpwent: malformed password entry (no :)\n"));
276 * As 256 is shorter than a pstring we don't need to check
277 * length here - if this ever changes....
279 strncpy(user_name, linebuf, PTR_DIFF(p, linebuf));
280 user_name[PTR_DIFF(p, linebuf)] = '\0';
284 p++; /* Go past ':' */
286 DEBUG(0, ("getsmbpwent: malformed password entry (uid not number)\n"));
290 uidval = atoi((char *) p);
292 while (*p && isdigit(*p))
296 DEBUG(0, ("getsmbpwent: malformed password entry (no : after uid)\n"));
300 pw_buf.smb_name = user_name;
301 pw_buf.smb_userid = uidval;
304 * Now get the password value - this should be 32 hex digits
305 * which are the ascii representations of a 16 byte string.
306 * Get two at a time and put them into the password.
312 if (*p == '*' || *p == 'X') {
313 /* Password deliberately invalid - end here. */
314 DEBUG(10, ("getsmbpwent: entry invalidated for user %s\n", user_name));
315 pw_buf.smb_nt_passwd = NULL;
316 pw_buf.smb_passwd = NULL;
317 pw_buf.acct_ctrl |= ACB_DISABLED;
321 if (linebuf_len < (PTR_DIFF(p, linebuf) + 33)) {
322 DEBUG(0, ("getsmbpwent: malformed password entry (passwd too short)\n"));
327 DEBUG(0, ("getsmbpwent: malformed password entry (no terminating :)\n"));
331 if (!strncasecmp((char *) p, "NO PASSWORD", 11)) {
332 pw_buf.smb_passwd = NULL;
333 pw_buf.acct_ctrl |= ACB_PWNOTREQ;
335 if (!pdb_gethexpwd((char *)p, (char *)smbpwd)) {
336 DEBUG(0, ("getsmbpwent: Malformed Lanman password entry (non hex chars)\n"));
339 pw_buf.smb_passwd = smbpwd;
343 * Now check if the NT compatible password is
346 pw_buf.smb_nt_passwd = NULL;
348 p += 33; /* Move to the first character of the line after
349 the lanman password. */
350 if ((linebuf_len >= (PTR_DIFF(p, linebuf) + 33)) && (p[32] == ':')) {
351 if (*p != '*' && *p != 'X') {
352 if(pdb_gethexpwd((char *)p,(char *)smbntpwd))
353 pw_buf.smb_nt_passwd = smbntpwd;
355 p += 33; /* Move to the first character of the line after
359 DEBUG(5, ("getsmbpwent: returning passwd entry for user %s, uid %d\n",
364 pw_buf.acct_ctrl = pdb_decode_acct_ctrl(p);
366 /* Must have some account type set. */
367 if(pw_buf.acct_ctrl == 0)
368 pw_buf.acct_ctrl = ACB_NORMAL;
370 /* Now try and get the last change time. */
375 if(*p && StrnCaseCmp((char *)p, "LCT-", 4)) {
378 for(i = 0; i < 8; i++) {
379 if(p[i] == '\0' || !isxdigit(p[i]))
384 * p points at 8 characters of hex digits -
385 * read into a time_t as the seconds since
386 * 1970 that the password was last changed.
388 pw_buf.pass_last_set_time = (time_t)strtol((char *)p, NULL, 16);
393 /* 'Old' style file. Fake up based on user name. */
395 * Currently trust accounts are kept in the same
396 * password file as 'normal accounts'. If this changes
397 * we will have to fix this code. JRA.
399 if(pw_buf.smb_name[strlen(pw_buf.smb_name) - 1] == '$') {
400 pw_buf.acct_ctrl &= ~ACB_NORMAL;
401 pw_buf.acct_ctrl |= ACB_WSTRUST;
408 DEBUG(5,("getsmbpwent: end of file reached.\n"));
412 /*************************************************************************
413 Return the current position in the smbpasswd list as an unsigned long.
414 This must be treated as an opaque token.
416 do not call this function directly. use passdb.c instead.
418 *************************************************************************/
419 unsigned long getsmbpwpos(void *vp)
421 return (unsigned long)ftell((FILE *)vp);
424 /*************************************************************************
425 Set the current position in the smbpasswd list from unsigned long.
426 This must be treated as an opaque token.
428 do not call this function directly. use passdb.c instead.
430 *************************************************************************/
431 BOOL setsmbpwpos(void *vp, unsigned long tok)
433 return !fseek((FILE *)vp, tok, SEEK_SET);
436 /************************************************************************
437 Routine to add an entry to the smbpasswd file.
439 do not call this function directly. use passdb.c instead.
441 *************************************************************************/
442 BOOL add_smb21pwd_entry(struct sam_passwd *newpwd)
447 /************************************************************************
448 Routine to add an entry to the smbpasswd file.
450 do not call this function directly. use passdb.c instead.
452 *************************************************************************/
453 BOOL add_smbpwd_entry(struct smb_passwd *newpwd)
455 char *pfile = lp_smb_passwd_file();
456 struct smb_passwd *pwd = NULL;
463 int new_entry_length;
464 unsigned char *new_entry;
468 /* Open the smbpassword file - for update. */
469 fp = startsmbpwent(True);
472 DEBUG(0, ("add_smbpwd_entry: unable to open file.\n"));
477 * Scan the file, a line at a time and check if the name matches.
480 while ((pwd = getsmbpwent(fp)) != NULL) {
481 if (strequal(newpwd->smb_name, pwd->smb_name)) {
482 DEBUG(0, ("add_smbpwd_entry: entry with name %s already exists\n", pwd->smb_name));
488 /* Ok - entry doesn't exist. We can add it */
490 /* Create a new smb passwd entry and set it to the given password. */
492 * The add user write needs to be atomic - so get the fd from
493 * the fp and do a raw write() call.
497 if((offpos = lseek(fd, 0, SEEK_END)) == -1) {
498 DEBUG(0, ("add_smbpwd_entry(lseek): Failed to add entry for user %s to file %s. \
499 Error was %s\n", newpwd->smb_name, pfile, strerror(errno)));
504 new_entry_length = strlen(newpwd->smb_name) + 1 + 15 + 1 + 32 + 1 + 32 + 1 + 5 + 1 + 13 + 2;
506 if((new_entry = (char *)malloc( new_entry_length )) == NULL) {
507 DEBUG(0, ("add_smbpwd_entry(malloc): Failed to add entry for user %s to file %s. \
508 Error was %s\n", newpwd->smb_name, pfile, strerror(errno)));
513 slprintf(new_entry, new_entry_length - 1, "%s:%u:", newpwd->smb_name, (unsigned)newpwd->smb_userid);
514 p = (unsigned char *)&new_entry[strlen(new_entry)];
516 if(newpwd->smb_passwd != NULL) {
517 for( i = 0; i < 16; i++) {
518 slprintf((char *)&p[i*2], new_entry_length - (p - new_entry) - 1, "%02X", newpwd->smb_passwd[i]);
522 if(newpwd->acct_ctrl & ACB_PWNOTREQ)
523 safe_strcpy((char *)p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", new_entry_length - 1 - (p - new_entry));
525 safe_strcpy((char *)p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", new_entry_length - 1 - (p - new_entry));
532 if(newpwd->smb_nt_passwd != NULL) {
533 for( i = 0; i < 16; i++) {
534 slprintf((char *)&p[i*2], new_entry_length - 1 - (p - new_entry), "%02X", newpwd->smb_nt_passwd[i]);
537 if(newpwd->acct_ctrl & ACB_PWNOTREQ)
538 safe_strcpy((char *)p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", new_entry_length - 1 - (p - new_entry));
540 safe_strcpy((char *)p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", new_entry_length - 1 - (p - new_entry));
547 /* Add the account encoding and the last change time. */
548 slprintf((char *)p, new_entry_length - 1 - (p - new_entry), "%s:LCT-%08X:\n",
549 pdb_encode_acct_ctrl(newpwd->acct_ctrl),
552 #ifdef DEBUG_PASSWORD
553 DEBUG(100, ("add_smbpwd_entry(%d): new_entry_len %d entry_len %d made line |%s|",
554 fd, new_entry_length, strlen(new_entry), new_entry));
557 if ((wr_len = write(fd, new_entry, strlen(new_entry))) != strlen(new_entry)) {
558 DEBUG(0, ("add_smbpwd_entry(write): %d Failed to add entry for user %s to file %s. \
559 Error was %s\n", wr_len, newpwd->smb_name, pfile, strerror(errno)));
561 /* Remove the entry we just wrote. */
562 if(ftruncate(fd, offpos) == -1) {
563 DEBUG(0, ("add_smbpwd_entry: ERROR failed to ftruncate file %s. \
564 Error was %s. Password file may be corrupt ! Please examine by hand !\n",
565 newpwd->smb_name, strerror(errno)));
576 /************************************************************************
577 Routine to search the smbpasswd file for an entry matching the username.
578 and then modify its password entry. We can't use the startsmbpwent()/
579 getsmbpwent()/endsmbpwent() interfaces here as we depend on looking
580 in the actual file to decide how much room we have to write data.
581 override = False, normal
582 override = True, override XXXXXXXX'd out password or NO PASS
584 do not call this function directly. use passdb.c instead.
586 ************************************************************************/
587 BOOL mod_smb21pwd_entry(struct sam_passwd* pwd, BOOL override)
592 /************************************************************************
593 Routine to search the smbpasswd file for an entry matching the username.
594 and then modify its password entry. We can't use the startsmbpwent()/
595 getsmbpwent()/endsmbpwent() interfaces here as we depend on looking
596 in the actual file to decide how much room we have to write data.
597 override = False, normal
598 override = True, override XXXXXXXX'd out password or NO PASS
600 do not call this function directly. use passdb.c instead.
602 ************************************************************************/
603 BOOL mod_smbpwd_entry(struct smb_passwd* pwd, BOOL override)
605 /* Static buffers we will return. */
606 static pstring user_name;
609 char readbuf[16 * 1024];
613 unsigned char *p = NULL;
614 long linebuf_len = 0;
617 char *pfile = lp_smb_passwd_file();
618 BOOL found_entry = False;
619 BOOL got_pass_last_set_time = False;
621 long pwd_seekpos = 0;
628 DEBUG(0, ("No SMB password file set\n"));
631 DEBUG(10, ("mod_smbpwd_entry: opening file %s\n", pfile));
633 fp = fopen(pfile, "r+");
636 DEBUG(0, ("mod_smbpwd_entry: unable to open file %s\n", pfile));
639 /* Set a 16k buffer to do more efficient reads */
640 setvbuf(fp, readbuf, _IOFBF, sizeof(readbuf));
644 if (!pw_file_lock(lockfd, F_WRLCK, 5, &pw_file_lock_depth)) {
645 DEBUG(0, ("mod_smbpwd_entry: unable to lock file %s\n", pfile));
650 /* Make sure it is only rw by the owner */
653 /* We have a write lock on the file. */
655 * Scan the file, a line at a time and check if the name matches.
658 pwd_seekpos = ftell(fp);
662 fgets(linebuf, sizeof(linebuf), fp);
664 pw_file_unlock(lockfd, &pw_file_lock_depth);
670 * Check if the string is terminated with a newline - if not
671 * then we must keep reading and discard until we get one.
673 linebuf_len = strlen(linebuf);
674 if (linebuf[linebuf_len - 1] != '\n') {
676 while (!ferror(fp) && !feof(fp)) {
683 linebuf[linebuf_len - 1] = '\0';
686 #ifdef DEBUG_PASSWORD
687 DEBUG(100, ("mod_smbpwd_entry: got line |%s|\n", linebuf));
690 if ((linebuf[0] == 0) && feof(fp)) {
691 DEBUG(4, ("mod_smbpwd_entry: end of file reached\n"));
696 * The line we have should be of the form :-
698 * username:uid:[32hex bytes]:....other flags presently
703 * username:uid:[32hex bytes]:[32hex bytes]:....ignored....
705 * if Windows NT compatible passwords are also present.
708 if (linebuf[0] == '#' || linebuf[0] == '\0') {
709 DEBUG(6, ("mod_smbpwd_entry: skipping comment or blank line\n"));
713 p = (unsigned char *) strchr(linebuf, ':');
716 DEBUG(0, ("mod_smbpwd_entry: malformed password entry (no :)\n"));
721 * As 256 is shorter than a pstring we don't need to check
722 * length here - if this ever changes....
724 strncpy(user_name, linebuf, PTR_DIFF(p, linebuf));
725 user_name[PTR_DIFF(p, linebuf)] = '\0';
726 if (strequal(user_name, pwd->smb_name)) {
732 if (!found_entry) return False;
734 DEBUG(6, ("mod_smbpwd_entry: entry exists\n"));
736 /* User name matches - get uid and password */
737 p++; /* Go past ':' */
740 DEBUG(0, ("mod_smbpwd_entry: malformed password entry (uid not number)\n"));
741 pw_file_unlock(lockfd, &pw_file_lock_depth);
746 while (*p && isdigit(*p))
749 DEBUG(0, ("mod_smbpwd_entry: malformed password entry (no : after uid)\n"));
750 pw_file_unlock(lockfd, &pw_file_lock_depth);
756 * Now get the password value - this should be 32 hex digits
757 * which are the ascii representations of a 16 byte string.
758 * Get two at a time and put them into the password.
762 /* Record exact password position */
763 pwd_seekpos += PTR_DIFF(p, linebuf);
765 if (!override && (*p == '*' || *p == 'X')) {
766 /* Password deliberately invalid - end here. */
767 DEBUG(10, ("mod_smbpwd_entry: entry invalidated for user %s\n", user_name));
768 pw_file_unlock(lockfd, &pw_file_lock_depth);
773 if (linebuf_len < (PTR_DIFF(p, linebuf) + 33)) {
774 DEBUG(0, ("mod_smbpwd_entry: malformed password entry (passwd too short)\n"));
775 pw_file_unlock(lockfd,&pw_file_lock_depth);
781 DEBUG(0, ("mod_smbpwd_entry: malformed password entry (no terminating :)\n"));
782 pw_file_unlock(lockfd,&pw_file_lock_depth);
787 if (!override && (*p == '*' || *p == 'X')) {
788 pw_file_unlock(lockfd,&pw_file_lock_depth);
793 /* Now check if the NT compatible password is
795 p += 33; /* Move to the first character of the line after
796 the lanman password. */
797 if (linebuf_len < (PTR_DIFF(p, linebuf) + 33)) {
798 DEBUG(0, ("mod_smbpwd_entry: malformed password entry (passwd too short)\n"));
799 pw_file_unlock(lockfd,&pw_file_lock_depth);
805 DEBUG(0, ("mod_smbpwd_entry: malformed password entry (no terminating :)\n"));
806 pw_file_unlock(lockfd,&pw_file_lock_depth);
812 * Now check if the account info and the password last
813 * change time is available.
815 p += 33; /* Move to the first character of the line after
822 while((linebuf_len > PTR_DIFF(p, linebuf)) && (*p != ']'))
823 encode_bits[i++] = *p++;
825 encode_bits[i] = '\0';
827 /* Go past the ']' */
828 if(linebuf_len > PTR_DIFF(p, linebuf))
831 if((linebuf_len > PTR_DIFF(p, linebuf)) && (*p == ':')) {
834 /* We should be pointing at the TLC entry. */
835 if((linebuf_len > (PTR_DIFF(p, linebuf) + 13)) && StrnCaseCmp((char *)p, "LCT-", 4)) {
838 for(i = 0; i < 8; i++) {
839 if(p[i] == '\0' || !isxdigit(p[i]))
844 * p points at 8 characters of hex digits -
845 * read into a time_t as the seconds since
846 * 1970 that the password was last changed.
848 got_pass_last_set_time = True;
850 } /* *p && StrnCaseCmp() */
854 /* Entry is correctly formed. */
857 * Do an atomic write into the file at the position defined by
861 /* The mod user write needs to be atomic - so get the fd from
862 the fp and do a raw write() call.
867 if (lseek(fd, pwd_seekpos - 1, SEEK_SET) != pwd_seekpos - 1) {
868 DEBUG(0, ("mod_smbpwd_entry: seek fail on file %s.\n", pfile));
869 pw_file_unlock(lockfd,&pw_file_lock_depth);
874 /* Sanity check - ensure the character is a ':' */
875 if (read(fd, &c, 1) != 1) {
876 DEBUG(0, ("mod_smbpwd_entry: read fail on file %s.\n", pfile));
877 pw_file_unlock(lockfd,&pw_file_lock_depth);
883 DEBUG(0, ("mod_smbpwd_entry: check on passwd file %s failed.\n", pfile));
884 pw_file_unlock(lockfd,&pw_file_lock_depth);
889 /* Create the 32 byte representation of the new p16 */
890 if(pwd->smb_passwd != NULL) {
891 for (i = 0; i < 16; i++) {
892 slprintf(&ascii_p16[i*2], sizeof(fstring) - 1, "%02X", (uchar) pwd->smb_passwd[i]);
895 if(pwd->acct_ctrl & ACB_PWNOTREQ)
896 fstrcpy(ascii_p16, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX");
898 fstrcpy(ascii_p16, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
901 /* Add on the NT md4 hash */
904 if (pwd->smb_nt_passwd != NULL) {
905 for (i = 0; i < 16; i++) {
906 slprintf(&ascii_p16[(i*2)+33], sizeof(fstring) - 1, "%02X", (uchar) pwd->smb_nt_passwd[i]);
909 if(pwd->acct_ctrl & ACB_PWNOTREQ)
910 fstrcpy(&ascii_p16[33], "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX");
912 fstrcpy(&ascii_p16[33], "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
915 /* Add on the account info bits and the time of last
918 pwd->pass_last_set_time = time(NULL);
920 if(got_pass_last_set_time) {
921 slprintf(&ascii_p16[strlen(ascii_p16)],
922 sizeof(ascii_p16)-(strlen(ascii_p16)+1),
924 encode_bits, (uint32)pwd->pass_last_set_time );
925 wr_len = strlen(ascii_p16);
928 #ifdef DEBUG_PASSWORD
929 DEBUG(100,("mod_smbpwd_entry: "));
930 dump_data(100, ascii_p16, wr_len);
933 if (write(fd, ascii_p16, wr_len) != wr_len) {
934 DEBUG(0, ("mod_smbpwd_entry: write failed in passwd file %s\n", pfile));
935 pw_file_unlock(lockfd,&pw_file_lock_depth);
940 pw_file_unlock(lockfd,&pw_file_lock_depth);
945 static void dummy_function(void) { } /* stop some compilers complaining */
946 #endif /* USE_SMBPASS_DB */