summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJelmer Vernooij <jelmer@samba.org>2005-08-29 22:01:18 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:34:57 -0500
commitec934124db8a5234d8c83799a23c7bdced5dd95a (patch)
tree1cc89a41482b16b186f9bec3daad692d9dbcfed2
parent721b22f9cdef811ac0e2738b62d7b978fad74dbc (diff)
downloadsamba-ec934124db8a5234d8c83799a23c7bdced5dd95a.tar.gz
samba-ec934124db8a5234d8c83799a23c7bdced5dd95a.tar.bz2
samba-ec934124db8a5234d8c83799a23c7bdced5dd95a.zip
r9762: Add support for reading good old smbpasswd files
Fix password support Make base64 decode/encode functions available to EJS (This used to be commit 1376a1fe44cd6b01709819095a711c14626b1d3e)
-rw-r--r--source4/lib/samba3/samba3.h4
-rw-r--r--source4/lib/samba3/smbpasswd.c132
-rw-r--r--source4/lib/samba3/tdbsam.c32
-rw-r--r--source4/scripting/ejs/smbcalls_ldb.c61
-rw-r--r--source4/scripting/ejs/smbcalls_samba3.c4
-rw-r--r--source4/scripting/libjs/upgrade.js59
6 files changed, 250 insertions, 42 deletions
diff --git a/source4/lib/samba3/samba3.h b/source4/lib/samba3/samba3.h
index 5aba790c4e..a41109a145 100644
--- a/source4/lib/samba3/samba3.h
+++ b/source4/lib/samba3/samba3.h
@@ -22,6 +22,7 @@
#define _SAMBA3_H
#include "librpc/gen_ndr/security.h"
+#include "librpc/gen_ndr/samr.h"
struct samba3_samaccount {
uint32_t logon_time,
@@ -43,10 +44,11 @@ struct samba3_samaccount {
char *profile_path;
char *acct_desc;
char *workstations;
+ uid_t uid;
uint32_t user_rid, group_rid, hours_len, unknown_6;
uint16_t acct_ctrl, logon_divs;
uint16_t bad_password_count, logon_count;
- uint8_t *lm_pw_ptr, *nt_pw_ptr;
+ struct samr_Password lm_pw, nt_pw;
uint8_t *nt_pw_hist_ptr;
uint8_t *hours;
};
diff --git a/source4/lib/samba3/smbpasswd.c b/source4/lib/samba3/smbpasswd.c
index bcbb5e56d8..5976d2db57 100644
--- a/source4/lib/samba3/smbpasswd.c
+++ b/source4/lib/samba3/smbpasswd.c
@@ -7,6 +7,7 @@
Modified by Gerald (Jerry) Carter 2000-2001
Copyright (C) Tim Potter 2001
Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005
+ Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -54,6 +55,7 @@
#include "includes.h"
#include "librpc/gen_ndr/ndr_samr.h"
+#include "lib/samba3/samba3.h"
#include "system/iconv.h"
/*! Convert 32 hex characters into a 16 byte array. */
@@ -206,3 +208,133 @@ char *smbpasswd_encode_acb_info(TALLOC_CTX *mem_ctx, uint16_t acb_info)
return acct_str;
}
+
+NTSTATUS samba3_read_smbpasswd(const char *filename, TALLOC_CTX *ctx, struct samba3_samaccount **accounts, uint32_t *count)
+{
+ int numlines;
+ char **lines;
+ *count = 0;
+ *accounts = NULL;
+ int i;
+
+ lines = file_lines_load(filename, &numlines, ctx);
+
+ *accounts = talloc_array(ctx, struct samba3_samaccount, numlines);
+
+ for (i = 0; i < numlines; i++) {
+ char *p = lines[i], *q;
+ struct samba3_samaccount *acc = &((*accounts)[*count]);
+
+ if (p[0] == '\0' || p[0] == '#')
+ continue;
+
+ ZERO_STRUCTP(acc);
+
+ q = strchr(p, ':');
+ if (!q) {
+ DEBUG(0, ("%s:%d: expected ':'\n", filename, i));
+ continue;
+ }
+
+ acc->username = talloc_strndup(ctx, p, PTR_DIFF(q, p));
+ p = q+1;
+
+ acc->uid = atoi(p);
+
+ q = strchr(p, ':');
+ if (!q) {
+ DEBUG(0, ("%s:%d: expected ':'\n", filename, i));
+ continue;
+ }
+ p = q+1;
+
+ if (strlen(p) < 33) {
+ DEBUG(0, ("%s:%d: expected 32 byte password blob\n", filename, i));
+ continue;
+ }
+
+ if (!strncmp(p, "NO PASSWORD", strlen("NO PASSWORD"))) {
+ acc->acct_ctrl |= ACB_PWNOTREQ;
+ } else if (p[0] == '*' || p[0] == 'X') {
+ /* No password set */
+ } else {
+ struct samr_Password *pw = smbpasswd_gethexpwd(*accounts, p);
+
+ if (!pw) {
+ DEBUG(0, ("%s:%d: Malformed LM pw entry\n", filename, i));
+ continue;
+ }
+
+ memcpy(acc->lm_pw.hash, pw, sizeof(*pw));
+ }
+
+ if (p[32] != ':') {
+ DEBUG(0, ("%s:%d: expected ':' after 32 byte password blob\n", filename, i));
+ continue;
+ }
+
+ p += 33;
+
+ if (p[0] == '*' || p[0] == 'X') {
+ /* No password set */
+ } else {
+ struct samr_Password *pw = smbpasswd_gethexpwd(*accounts, p);
+
+ if (!pw) {
+ DEBUG(0, ("%s:%d: Malformed LM pw entry\n", filename, i));
+ continue;
+ }
+
+ memcpy(acc->nt_pw.hash, pw, sizeof(*pw));
+ }
+
+ if (p[32] != ':') {
+ DEBUG(0, ("%s:%d: expected ':' after 32 byte password blob\n", filename, i));
+ continue;
+ }
+
+ p += 33;
+
+ if (p[0] == '[') {
+ q = strchr(p, ']');
+ if (!q) {
+ DEBUG(0, ("%s:%d: expected ']'\n", filename, i));
+ continue;
+ }
+
+ acc->acct_ctrl |= smbpasswd_decode_acb_info(p);
+
+ p = q+1;
+ if (p[0] == ':' && strncmp(p, "LCT-", 4) == 0) {
+ int j;
+ p += 4;
+
+ for(j = 0; j < 8; j++) {
+ if(p[j] == '\0' || !isxdigit(p[j])) {
+ break;
+ }
+ }
+ if(i == 8) {
+ acc->pass_last_set_time = (time_t)strtol((char *)p, NULL, 16);
+ }
+ }
+ } else {
+ /* 'Old' style file. Fake up based on user name. */
+ /*
+ * Currently trust accounts are kept in the same
+ * password file as 'normal accounts'. If this changes
+ * we will have to fix this code. JRA.
+ */
+ if(acc->username[strlen(acc->username) - 1] == '$') {
+ acc->acct_ctrl &= ~ACB_NORMAL;
+ acc->acct_ctrl |= ACB_WSTRUST;
+ }
+ }
+
+ (*count)++;
+ }
+
+ talloc_free(lines);
+
+ return NT_STATUS_OK;
+}
diff --git a/source4/lib/samba3/tdbsam.c b/source4/lib/samba3/tdbsam.c
index c9b121ca77..fc293d5df9 100644
--- a/source4/lib/samba3/tdbsam.c
+++ b/source4/lib/samba3/tdbsam.c
@@ -69,8 +69,8 @@ static BOOL init_sam_from_buffer_v0(TDB_CONTEXT *tdb, struct samba3_samaccount *
&munged_dial_len, &sampass->munged_dial, /* B */
&sampass->user_rid, /* d */
&sampass->group_rid, /* d */
- &lm_pw_len, &sampass->lm_pw_ptr, /* B */
- &nt_pw_len, &sampass->nt_pw_ptr, /* B */
+ &lm_pw_len, sampass->lm_pw.hash, /* B */
+ &nt_pw_len, sampass->nt_pw.hash, /* B */
&sampass->acct_ctrl, /* w */
&remove_me, /* remove on the next TDB_FORMAT upgarde */ /* d */
&sampass->logon_divs, /* w */
@@ -85,11 +85,11 @@ static BOOL init_sam_from_buffer_v0(TDB_CONTEXT *tdb, struct samba3_samaccount *
}
if (lm_pw_len != 16) {
- sampass->lm_pw_ptr = NULL;
+ return False;
}
if (nt_pw_len != 16) {
- sampass->nt_pw_ptr = NULL;
+ return False;
}
return True;
@@ -135,8 +135,8 @@ static BOOL init_sam_from_buffer_v1(TDB_CONTEXT *tdb, struct samba3_samaccount *
&munged_dial_len, &sampass->munged_dial, /* B */
&sampass->user_rid, /* d */
&sampass->group_rid, /* d */
- &lm_pw_len, &sampass->lm_pw_ptr, /* B */
- &nt_pw_len, &sampass->nt_pw_ptr, /* B */
+ &lm_pw_len, sampass->lm_pw.hash, /* B */
+ &nt_pw_len, sampass->nt_pw.hash, /* B */
&sampass->acct_ctrl, /* w */
&remove_me, /* d */
&sampass->logon_divs, /* w */
@@ -150,12 +150,12 @@ static BOOL init_sam_from_buffer_v1(TDB_CONTEXT *tdb, struct samba3_samaccount *
return False;
}
- if (sampass->lm_pw_ptr && lm_pw_len != 16) {
- sampass->lm_pw_ptr = NULL;
+ if (lm_pw_len != 16) {
+ return False;
}
- if (sampass->nt_pw_ptr && nt_pw_len != 16) {
- sampass->nt_pw_ptr = NULL;
+ if (nt_pw_len != 16) {
+ return False;
}
return True;
@@ -199,8 +199,8 @@ static BOOL init_sam_from_buffer_v2(TDB_CONTEXT *tdb, struct samba3_samaccount *
&munged_dial_len, &sampass->munged_dial, /* B */
&sampass->user_rid, /* d */
&sampass->group_rid, /* d */
- &lm_pw_len, &sampass->lm_pw_ptr, /* B */
- &nt_pw_len, &sampass->nt_pw_ptr, /* B */
+ &lm_pw_len, sampass->lm_pw.hash, /* B */
+ &nt_pw_len, sampass->nt_pw.hash, /* B */
/* Change from V1 is addition of password history field. */
&nt_pw_hist_len, &sampass->nt_pw_hist_ptr, /* B */
&sampass->acct_ctrl, /* w */
@@ -216,12 +216,12 @@ static BOOL init_sam_from_buffer_v2(TDB_CONTEXT *tdb, struct samba3_samaccount *
return False;
}
- if (sampass->lm_pw_ptr && lm_pw_len != 16) {
- sampass->lm_pw_ptr = NULL;
+ if (lm_pw_len != 16) {
+ return False;
}
- if (sampass->nt_pw_ptr && nt_pw_len != 16) {
- sampass->nt_pw_ptr = NULL;
+ if (nt_pw_len != 16) {
+ return False;
}
return True;
diff --git a/source4/scripting/ejs/smbcalls_ldb.c b/source4/scripting/ejs/smbcalls_ldb.c
index aaed14dd8c..662da0d971 100644
--- a/source4/scripting/ejs/smbcalls_ldb.c
+++ b/source4/scripting/ejs/smbcalls_ldb.c
@@ -4,6 +4,7 @@
provide hooks into smbd C calls from ejs scripts
Copyright (C) Andrew Tridgell 2005
+ Copyright (C) Jelmer Vernooij 2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -247,6 +248,64 @@ static int ejs_ldbErrstring(MprVarHandle eid, int argc, struct MprVar **argv)
return 0;
}
+/*
+ base64 encode
+ usage:
+ dataout = ldb.encode(datain)
+ */
+static int ejs_base64encode(MprVarHandle eid, int argc, struct MprVar **argv)
+{
+ char *ret;
+ DATA_BLOB *blob;
+
+ if (argc != 1) {
+ ejsSetErrorMsg(eid, "ldb.base64encode invalid argument count");
+ return -1;
+ }
+
+ blob = mprToDataBlob(argv[0]);
+ ret = ldb_base64_encode(mprMemCtx(), (char *)blob->data, blob->length);
+
+ if (!ret) {
+ mpr_Return(eid, mprCreateUndefinedVar());
+ } else {
+ mpr_Return(eid, mprString(ret));
+ }
+
+ talloc_free(ret);
+
+ return 0;
+}
+
+/*
+ base64 decode
+ usage:
+ dataout = ldb.decode(datain)
+ */
+static int ejs_base64decode(MprVarHandle eid, int argc, struct MprVar **argv)
+{
+ char *tmp;
+ int ret;
+
+ if (argc != 1) {
+ ejsSetErrorMsg(eid, "ldb.base64encode invalid argument count");
+ return -1;
+ }
+
+ tmp = talloc_strdup(mprMemCtx(), mprToString(argv[0]));
+ ret = ldb_base64_decode(tmp);
+ if (ret == -1) {
+ mpr_Return(eid, mprCreateUndefinedVar());
+ } else {
+ mpr_Return(eid, mprData((uint8_t *)tmp, ret));
+ }
+
+ talloc_free(tmp);
+
+ return 0;
+}
+
+
/*
perform an ldb modify
@@ -312,6 +371,8 @@ static int ejs_ldb_init(MprVarHandle eid, int argc, struct MprVar **argv)
mprSetCFunction(ldb, "del", ejs_ldbDelete);
mprSetCFunction(ldb, "rename", ejs_ldbRename);
mprSetCFunction(ldb, "errstring", ejs_ldbErrstring);
+ mprSetCFunction(ldb, "encode", ejs_base64encode);
+ mprSetCFunction(ldb, "decode", ejs_base64decode);
mprSetVar(ldb, "SCOPE_BASE", mprCreateNumberVar(LDB_SCOPE_BASE));
mprSetVar(ldb, "SCOPE_ONE", mprCreateNumberVar(LDB_SCOPE_ONELEVEL));
mprSetVar(ldb, "SCOPE_SUBTREE", mprCreateNumberVar(LDB_SCOPE_SUBTREE));
diff --git a/source4/scripting/ejs/smbcalls_samba3.c b/source4/scripting/ejs/smbcalls_samba3.c
index e6f6481060..eb37168bc8 100644
--- a/source4/scripting/ejs/smbcalls_samba3.c
+++ b/source4/scripting/ejs/smbcalls_samba3.c
@@ -343,8 +343,8 @@ static struct MprVar mprSamAccounts(struct samba3 *samba3)
mprSetVar(&m, "profile_path", mprString(a->profile_path));
mprSetVar(&m, "acct_desc", mprString(a->acct_desc));
mprSetVar(&m, "workstations", mprString(a->workstations));
-
- /* FIXME: lm_pw_ptr, nt_pw_ptr */
+ mprSetVar(&m, "lm_pw", mprData(a->lm_pw.hash, 16));
+ mprSetVar(&m, "nt_pw", mprData(a->nt_pw.hash, 16));
mprAddArray(&mpv, i, m);
}
diff --git a/source4/scripting/libjs/upgrade.js b/source4/scripting/libjs/upgrade.js
index 682721e931..dbf1c0f2c3 100644
--- a/source4/scripting/libjs/upgrade.js
+++ b/source4/scripting/libjs/upgrade.js
@@ -101,6 +101,7 @@ samba3RefuseMachinePwdChange: %d
function upgrade_sam_account(acc,domaindn)
{
+ var ldb = ldb_init();
var ldif = sprintf(
"dn: cn=%s,%s
objectClass: top
@@ -115,6 +116,8 @@ description: %s
primaryGroupID: %d
badPwdcount: %d
logonCount: %d
+ntPwdHash:: %s
+lmPwdHash:: %s
samba3Domain: %s
samba3DirDrive: %s
samba3MungedDial: %s
@@ -133,9 +136,8 @@ samba3Rid: %d
acc.fullname, acc.acct_desc, acc.group_rid, acc.bad_password_count, acc.logon_count,
acc.domain, acc.dir_drive, acc.munged_dial, acc.homedir, acc.logon_script,
acc.profile_path, acc.workstations, acc.kickoff_time, acc.bad_password_time,
-acc.pass_last_set_time, acc.pass_can_change_time, acc.pass_must_change_time, acc.user_rid);
-
- /* FIXME: Passwords */
+acc.pass_last_set_time, acc.pass_can_change_time, acc.pass_must_change_time, acc.user_rid,
+ ldb.encode(acc.lm_pw), ldb.encode(acc.nt_pw));
return ldif;
}
@@ -295,9 +297,6 @@ var keep = new Array(
"obey pam restrictions",
"password server",
"smb passwd file",
- "sam database",
- "spoolss database",
- "wins database",
"private dir",
"passwd chat",
"password level",
@@ -313,17 +312,6 @@ var keep = new Array(
"debuglevel",
"log file",
"smb ports",
- "nbt port",
- "dgram port",
- "cldap port",
- "krb5 port",
- "web port",
- "tls enabled",
- "tls keyfile",
- "tls certfile",
- "tls cafile",
- "tls crlfile",
- "swat directory",
"large readwrite",
"max protocol",
"min protocol",
@@ -344,12 +332,10 @@ var keep = new Array(
"use spnego",
"server signing",
"client signing",
- "rpc big endian",
"max connections",
"paranoid server security",
"socket options",
"strict sync",
- "case insensitive filesystem",
"max print jobs",
"printable",
"print ok",
@@ -375,10 +361,7 @@ var keep = new Array(
"lock dir",
"lock directory",
"pid directory",
- "js include",
- "setup directory",
"socket address",
- "-valid",
"copy",
"include",
"available",
@@ -394,6 +377,23 @@ function upgrade_smbconf(samba3)
//FIXME
}
+function save_smbconf(path,smbconf)
+{
+ var data = "
+# Generated by upgrade.js";
+
+ for (var i in smbconf.shares) {
+ var s = smbconf.shares[i];
+ data = data + "\n[" + s.name + "]\n";
+ for (var j in s.parameters) {
+ var p = s.parameters[j];
+ data = data + "\t" + p.name + " = " + p + "\n";
+ }
+ }
+
+ sys.file_save(path,data);
+}
+
function upgrade(subobj, samba3, message)
{
var samdb = ldb_init();
@@ -405,7 +405,20 @@ function upgrade(subobj, samba3, message)
ok = samdb.modify(ldif);
assert(ok);
- // FIXME: Enable samba3sam module if original passdb backend was ldap
+ var ldapurl = undefined;
+
+ // FIXME: figure out ldapurl
+
+ // Enable samba3sam module if original passdb backend was ldap
+ if (ldapurl != undefined) {
+ var ldif = sprintf("
+dn: @MAP=samba3sam
+@MAP_URL: %s", ldapurl);
+ samdb.add(ldif);
+
+ samdb.modify("dn: @MODULES
+@LIST: samldb,timestamps,objectguid,rdn_name");
+ }
message("Importing users\n");
for (var i in samba3.samaccounts) {