summaryrefslogtreecommitdiff
path: root/source3/passdb
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>1998-04-23 18:54:57 +0000
committerJeremy Allison <jra@samba.org>1998-04-23 18:54:57 +0000
commita85f5bc268a1c13334b86ac3a44a026359c09371 (patch)
tree3b7e688003d1037600a9f12b1947fcb5e42645d3 /source3/passdb
parentda4e61efad7c7c18595bec32dbb21a2045dadd2e (diff)
downloadsamba-a85f5bc268a1c13334b86ac3a44a026359c09371.tar.gz
samba-a85f5bc268a1c13334b86ac3a44a026359c09371.tar.bz2
samba-a85f5bc268a1c13334b86ac3a44a026359c09371.zip
genrand.c: Changed SMB_PASSWD_FILE to lp_smb_passwd_file().
password.c: Started the initial code for domain_client_validate(). All bracketed with #ifdef DOMAIN_CLIENT for now. reply.c: Call to domain_client_validate(). All bracketed with #ifdef DOMAIN_CLIENT for now. smbpass.c: New code to get/set machine passwords. Tidied up nesting of lock calls. Jeremy. (This used to be commit 89fe059a6816f32d2cc5c4c04c4089b60590e7e6)
Diffstat (limited to 'source3/passdb')
-rw-r--r--source3/passdb/smbpass.c255
1 files changed, 222 insertions, 33 deletions
diff --git a/source3/passdb/smbpass.c b/source3/passdb/smbpass.c
index f247cc100e..f3b38c43e7 100644
--- a/source3/passdb/smbpass.c
+++ b/source3/passdb/smbpass.c
@@ -38,7 +38,7 @@ static void gotalarm_sig(void)
seconds.
****************************************************************/
-static int do_pw_lock(int fd, int waitsecs, int type)
+static BOOL do_pw_lock(int fd, int waitsecs, int type)
{
struct flock lock;
int ret;
@@ -60,9 +60,10 @@ static int do_pw_lock(int fd, int waitsecs, int type)
if (gotalarm) {
DEBUG(0, ("do_pw_lock: failed to %s SMB passwd file.\n",
type == F_UNLCK ? "unlock" : "lock"));
- return -1;
+ return False;
}
- return ret;
+
+ return ((ret == 0) ? True : False);
}
static int pw_file_lock_depth;
@@ -71,35 +72,41 @@ static int pw_file_lock_depth;
Lock an fd. Abandon after waitsecs seconds.
****************************************************************/
-int pw_file_lock(int fd, int type, int secs)
+static BOOL pw_file_lock(int fd, int type, int secs, int *plock_depth)
{
if (fd < 0)
- return (-1);
+ return False;
+
+ (*plock_depth)++;
+
if(pw_file_lock_depth == 0) {
if (do_pw_lock(fd, secs, type)) {
- return -1;
+ DEBUG(10,("pw_file_lock: locking file failed, error = %s.\n",
+ strerror(errno)));
+ return False;
}
}
- pw_file_lock_depth++;
-
- return fd;
+ return True;
}
/***************************************************************
Unlock an fd. Abandon after waitsecs seconds.
****************************************************************/
-int pw_file_unlock(int fd)
+static BOOL pw_file_unlock(int fd, int *plock_depth)
{
- int ret = 0;
+ BOOL ret;
- if(pw_file_lock_depth == 1)
- ret = do_pw_lock(fd, 5, F_UNLCK);
+ if(*plock_depth == 1)
+ ret = do_pw_lock(fd, 5, F_UNLCK);
- pw_file_lock_depth--;
+ (*plock_depth)--;
- return ret;
+ if(ret == False)
+ DEBUG(10,("pw_file_unlock: unlocking file failed, error = %s.\n",
+ strerror(errno)));
+ return ret;
}
/***************************************************************
@@ -128,7 +135,7 @@ void *startsmbpwent(BOOL update)
/* Set a 16k buffer to do more efficient reads */
setvbuf(fp, s_readbuf, _IOFBF, sizeof(s_readbuf));
- if ((pw_file_lock(fileno(fp), F_RDLCK | (update ? F_WRLCK : 0), 5)) < 0) {
+ if ((pw_file_lock(fileno(fp), F_RDLCK | (update ? F_WRLCK : 0), 5, &pw_file_lock_depth)) == False) {
DEBUG(0, ("startsmbpwent: unable to lock file %s\n", pfile));
fclose(fp);
return NULL;
@@ -149,7 +156,7 @@ void endsmbpwent(void *vp)
{
FILE *fp = (FILE *)vp;
- pw_file_unlock(fileno(fp));
+ pw_file_unlock(fileno(fp), &pw_file_lock_depth);
fclose(fp);
DEBUG(7, ("endsmbpwent: closed password file.\n"));
}
@@ -764,7 +771,9 @@ BOOL mod_smbpwd_entry(struct smb_passwd* pwd)
/* Set a 16k buffer to do more efficient reads */
setvbuf(fp, readbuf, _IOFBF, sizeof(readbuf));
- if ((lockfd = pw_file_lock(fileno(fp), F_RDLCK | F_WRLCK, 5)) < 0) {
+ lockfd = fileno(fp);
+
+ if (pw_file_lock(lockfd, F_RDLCK | F_WRLCK, 5, &pw_file_lock_depth) == False) {
DEBUG(0, ("mod_smbpwd_entry: unable to lock file %s\n", pfile));
fclose(fp);
return False;
@@ -782,10 +791,10 @@ BOOL mod_smbpwd_entry(struct smb_passwd* pwd)
linebuf[0] = '\0';
- fgets(linebuf, 256, fp);
+ fgets(linebuf, sizeof(linebuf), fp);
if (ferror(fp)) {
+ pw_file_unlock(lockfd, &pw_file_lock_depth);
fclose(fp);
- pw_file_unlock(lockfd);
return False;
}
@@ -861,8 +870,8 @@ BOOL mod_smbpwd_entry(struct smb_passwd* pwd)
if (!isdigit(*p)) {
DEBUG(0, ("mod_smbpwd_entry: malformed password entry (uid not number)\n"));
+ pw_file_unlock(lockfd, &pw_file_lock_depth);
fclose(fp);
- pw_file_unlock(lockfd);
return False;
}
@@ -870,8 +879,8 @@ BOOL mod_smbpwd_entry(struct smb_passwd* pwd)
p++;
if (*p != ':') {
DEBUG(0, ("mod_smbpwd_entry: malformed password entry (no : after uid)\n"));
+ pw_file_unlock(lockfd, &pw_file_lock_depth);
fclose(fp);
- pw_file_unlock(lockfd);
return False;
}
@@ -888,28 +897,28 @@ BOOL mod_smbpwd_entry(struct smb_passwd* pwd)
if (*p == '*' || *p == 'X') {
/* Password deliberately invalid - end here. */
DEBUG(10, ("get_smbpwd_entry: entry invalidated for user %s\n", user_name));
+ pw_file_unlock(lockfd, &pw_file_lock_depth);
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"));
+ pw_file_unlock(lockfd,&pw_file_lock_depth);
fclose(fp);
- pw_file_unlock(lockfd);
return (False);
}
if (p[32] != ':') {
DEBUG(0, ("mod_smbpwd_entry: malformed password entry (no terminating :)\n"));
+ pw_file_unlock(lockfd,&pw_file_lock_depth);
fclose(fp);
- pw_file_unlock(lockfd);
return False;
}
if (*p == '*' || *p == 'X') {
+ pw_file_unlock(lockfd,&pw_file_lock_depth);
fclose(fp);
- pw_file_unlock(lockfd);
return False;
}
@@ -919,15 +928,15 @@ BOOL mod_smbpwd_entry(struct smb_passwd* pwd)
the lanman password. */
if (linebuf_len < (PTR_DIFF(p, linebuf) + 33)) {
DEBUG(0, ("mod_smbpwd_entry: malformed password entry (passwd too short)\n"));
+ pw_file_unlock(lockfd,&pw_file_lock_depth);
fclose(fp);
- pw_file_unlock(lockfd);
return (False);
}
if (p[32] != ':') {
DEBUG(0, ("mod_smbpwd_entry: malformed password entry (no terminating :)\n"));
+ pw_file_unlock(lockfd,&pw_file_lock_depth);
fclose(fp);
- pw_file_unlock(lockfd);
return False;
}
@@ -989,23 +998,23 @@ BOOL mod_smbpwd_entry(struct smb_passwd* pwd)
if (lseek(fd, pwd_seekpos - 1, SEEK_SET) != pwd_seekpos - 1) {
DEBUG(0, ("mod_smbpwd_entry: seek fail on file %s.\n", pfile));
+ pw_file_unlock(lockfd,&pw_file_lock_depth);
fclose(fp);
- pw_file_unlock(lockfd);
return False;
}
/* Sanity check - ensure the character is a ':' */
if (read(fd, &c, 1) != 1) {
DEBUG(0, ("mod_smbpwd_entry: read fail on file %s.\n", pfile));
+ pw_file_unlock(lockfd,&pw_file_lock_depth);
fclose(fp);
- pw_file_unlock(lockfd);
return False;
}
if (c != ':') {
DEBUG(0, ("mod_smbpwd_entry: check on passwd file %s failed.\n", pfile));
+ pw_file_unlock(lockfd,&pw_file_lock_depth);
fclose(fp);
- pw_file_unlock(lockfd);
return False;
}
@@ -1053,12 +1062,192 @@ BOOL mod_smbpwd_entry(struct smb_passwd* pwd)
if (write(fd, ascii_p16, wr_len) != wr_len) {
DEBUG(0, ("mod_smbpwd_entry: write failed in passwd file %s\n", pfile));
+ pw_file_unlock(lockfd,&pw_file_lock_depth);
fclose(fp);
- pw_file_unlock(lockfd);
return False;
}
+ pw_file_unlock(lockfd,&pw_file_lock_depth);
fclose(fp);
- pw_file_unlock(lockfd);
return True;
}
+
+#ifdef DOMAIN_CLIENT
+
+static int mach_passwd_lock_depth;
+
+/************************************************************************
+ Routine to lock the machine account password file for a domain.
+************************************************************************/
+
+void *machine_password_lock( char *domain, char *name, BOOL update)
+{
+ FILE *fp;
+ pstring mac_file;
+ unsigned int mac_file_len;
+ char *p;
+
+ if(mach_passwd_lock_depth == 0) {
+ pstrcpy(mac_file, lp_smb_passwd_file());
+ p = strrchr(mac_file, '/');
+ if(p != NULL)
+ *++p = '\0';
+ mac_file_len = strlen(mac_file);
+ if(sizeof(pstring) - mac_file_len - strlen(domain) - strlen(name) - 6) {
+ DEBUG(0,("machine_password_lock: path %s too long to add machine details.\n",
+ mac_file));
+ return NULL;
+ }
+
+ strcat(mac_file, domain);
+ strcat(mac_file, ".");
+ strcat(mac_file, name);
+ strcat(mac_file, ".mac");
+
+ if((fp = fopen(mac_file, "r+b")) == 0) {
+ DEBUG(0,("machine_password_lock: cannot open file %s. Error was %s.\n",
+ mac_file, strerror(errno) ));
+ return NULL;
+ }
+
+ chmod(mac_file, 0600);
+ }
+
+ if(pw_file_lock(fileno(fp), F_RDLCK | (update ? F_WRLCK : 0),
+ 60, &mach_passwd_lock_depth) == False) {
+ DEBUG(0,("machine_password_lock: cannot lock file %s.\n", mac_file));
+ fclose(fp);
+ return NULL;
+ }
+
+ return (void *)fp;
+}
+
+/************************************************************************
+ Routine to unlock the machine account password file for a domain.
+************************************************************************/
+
+BOOL machine_password_unlock( void *token )
+{
+ FILE *fp = (FILE *)token;
+ BOOL ret = pw_file_unlock(fileno(fp), &mach_passwd_lock_depth);
+ if(mach_passwd_lock_depth == 0)
+ fclose(fp);
+ return ret;
+}
+
+/************************************************************************
+ Routine to get the machine account password for a domain.
+ The user of this function must have locked the machine password file.
+************************************************************************/
+
+BOOL get_machine_account_password( void *mach_tok, unsigned char *ret_pwd,
+ time_t *last_change_time)
+{
+ FILE *fp = (FILE *)mach_tok;
+ char linebuf[256];
+ char *p;
+ int i;
+
+ linebuf[0] = '\0';
+
+ *last_change_time = (time_t)0;
+ memset(ret_pwd, '\0', 16);
+
+ if(fseek( fp, 0L, SEEK_SET) == -1) {
+ DEBUG(0,("get_machine_account_password: Failed to seek to start of file. Error was %s.\n",
+ strerror(errno) ));
+ return False;
+ }
+
+ fgets(linebuf, sizeof(linebuf), fp);
+ if(ferror(fp)) {
+ DEBUG(0,("get_machine_account_password: Failed to read password. Error was %s.\n",
+ strerror(errno) ));
+ return False;
+ }
+
+ /*
+ * The length of the line read
+ * must be 45 bytes ( <---XXXX 32 bytes-->:TLC-12345678
+ */
+
+ if(strlen(linebuf) != 45) {
+ DEBUG(0,("get_machine_account_password: Malformed machine password file (wrong length).\n"));
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("get_machine_account_password: line = |%s|\n", linebuf));
+#endif
+ return False;
+ }
+
+ /*
+ * Get the hex password.
+ */
+
+ if (!gethexpwd((char *)linebuf, (char *)ret_pwd) || linebuf[32] != ':' ||
+ strncmp(&linebuf[33], "TLC-", 4)) {
+ DEBUG(0,("get_machine_account_password: Malformed machine password file (incorrect format).\n"));
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("get_machine_account_password: line = |%s|\n", linebuf));
+#endif
+ return False;
+ }
+
+ /*
+ * Get the last changed time.
+ */
+ p = &linebuf[37];
+
+ for(i = 0; i < 8; i++) {
+ if(p[i] == '\0' || !isxdigit(p[i])) {
+ DEBUG(0,("get_machine_account_password: Malformed machine password file (no timestamp).\n"));
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("get_machine_account_password: line = |%s|\n", linebuf));
+#endif
+ return False;
+ }
+ }
+
+ /*
+ * p points at 8 characters of hex digits -
+ * read into a time_t as the seconds since
+ * 1970 that the password was last changed.
+ */
+
+ *last_change_time = (time_t)strtol(p, NULL, 16);
+
+ return True;
+}
+
+/************************************************************************
+ Routine to get the machine account password for a domain.
+ The user of this function must have locked the machine password file.
+************************************************************************/
+
+BOOL set_machine_account_password( void *mach_tok, unsigned char *md4_new_pwd)
+{
+ char linebuf[64];
+ int i;
+ FILE *fp = (FILE *)mach_tok;
+
+ if(fseek( fp, 0L, SEEK_SET) == -1) {
+ DEBUG(0,("set_machine_account_password: Failed to seek to start of file. Error was %s.\n",
+ strerror(errno) ));
+ return False;
+ }
+
+ for (i = 0; i < 16; i++)
+ sprintf(&linebuf[(i*2)], "%02X", md4_new_pwd[i]);
+
+ sprintf(&linebuf[32], ":TLC-%08X\n", (unsigned)time(NULL));
+
+ if(fwrite( linebuf, 1, 45, fp)!= 45) {
+ DEBUG(0,("set_machine_account_password: Failed to write file. Warning - the machine \
+machine account is now invalid. Please recreate. Error was %s.\n", strerror(errno) ));
+ return False;
+ }
+
+ fflush(fp);
+ return True;
+}
+#endif /* DOMAIN_CLIENT */