wmi-1.3.16 from opsview.com
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
This directory contains various files and functions for the purpose of
|
||||
Samba3 import, migration and compatibility.
|
||||
|
||||
For example, the first file in this directory (smbpasswd.c) handles
|
||||
portions of the smbpasswd file format.
|
||||
|
||||
The other files in this directory support reading the various
|
||||
TDB databases from Samba3.
|
||||
@@ -0,0 +1,68 @@
|
||||
--- Samba3 -> Samba4 Upgrade ---
|
||||
(C) 2005 Jelmer Vernooij <jelmer@samba.org>
|
||||
Published under the GNU GPL
|
||||
|
||||
Sponsored by the Google Summer of Code program (http://code.google.com/summerofcode.html)
|
||||
Mentored by Andrew Bartlett <abartlet@samba.org>
|
||||
Thanks!
|
||||
|
||||
Done:
|
||||
- Reading wins.dat
|
||||
- Reading registry.tdb
|
||||
- Reading passdb.tdb
|
||||
- Reading account_policy.tdb
|
||||
- Reading group_mappings.tdb
|
||||
- Reading winbindd_idmap.tdb
|
||||
- Reading share_info.tdb
|
||||
- Reading secrets.tdb
|
||||
- Reading smbpasswd
|
||||
- Reading + writing (generic) smb.conf files
|
||||
- Testsuite for read support mentioned above
|
||||
- Console utility for dumping Samba information
|
||||
- Import user accounts in Samba4
|
||||
- Import groups in Samba4
|
||||
- Import secrets in Samba4
|
||||
- Import WINS data in Samba4
|
||||
- Dump idmap data to LDB
|
||||
- Import registry keys/values in Samba4
|
||||
- Import account policies in Samba4
|
||||
- Testsuite for upgrade
|
||||
- Console utility from upgrading from Samba3 -> Samba4
|
||||
- SWAT (Web interface) support for upgrading from Samba3 -> Samba4
|
||||
- LDB generic mapping module
|
||||
- (Experimental) Samba4 LDB <-> Samba3 LDAP mapping module based on LDB generic mapping module
|
||||
- Testsuite for Samba4 LDB <-> Samba3 LDAP mapping module
|
||||
|
||||
Source files:
|
||||
source/lib/ldb/modules/ldb_map.c
|
||||
source/lib/ldb/modules/ldb_map.h
|
||||
source/lib/samba3/group.c
|
||||
source/lib/samba3/idmap.c
|
||||
source/lib/samba3/policy.c
|
||||
source/lib/samba3/registry.c
|
||||
source/lib/samba3/samba3.c
|
||||
source/lib/samba3/secrets.c
|
||||
source/lib/samba3/share_info.c
|
||||
source/lib/samba3/smbpasswd.c
|
||||
source/lib/samba3/tdbsam.c
|
||||
source/lib/samba3/winsdb.c
|
||||
source/lib/samba3/samba3.h
|
||||
source/scripting/libjs/upgrade.js
|
||||
source/scripting/ejs/smbcalls_param.c
|
||||
source/scripting/ejs/smbcalls_samba3.c
|
||||
source/param/generic.c
|
||||
source/param/generic.h
|
||||
testdata/samba3/verify
|
||||
testprogs/ejs/samba3sam
|
||||
source/setup/upgrade
|
||||
source/scripting/bin/samba3dump
|
||||
source/dsdb/samdb/ldb_modules/samba3sam.c
|
||||
source/script/tests/test_s3upgrade.sh
|
||||
swat/install/samba3.esp
|
||||
|
||||
Known remaining issues:
|
||||
- [upgrade] Conversion from the smbpasswd/TDB passwords to ntPwdHash / lmPwdHash is broken. Couldn't find out why.
|
||||
- [ldb_map] Conversion of attribute names in DN's is still a bit dodgy
|
||||
- [ldb_map] mapped objectClass names may be mentioned multiple times in returned records
|
||||
- [ldb_map] add/modify support not tested very well with LDAP yet (only LDB+TDB)
|
||||
- [ldb_map] group membership is not yet mapped (only primaryGroupID / sambaPrimaryGroupSID)
|
||||
@@ -0,0 +1,15 @@
|
||||
################################################
|
||||
# Start SUBSYSTEM LIBSAMBA3
|
||||
[LIBRARY::LIBSAMBA3]
|
||||
VERSION = 0.0.1
|
||||
SO_VERSION = 0
|
||||
DESCRIPTION = Library for reading Samba3 data files
|
||||
PRIVATE_PROTO_HEADER = samba3_proto.h
|
||||
PUBLIC_HEADERS = samba3.h
|
||||
OBJ_FILES = smbpasswd.o tdbsam.o policy.o \
|
||||
idmap.o winsdb.o samba3.o group.o \
|
||||
registry.o secrets.o share_info.o
|
||||
PRIVATE_DEPENDENCIES = LIBSAMBA-UTIL LIBTDB NDR_SECURITY \
|
||||
CREDENTIALS
|
||||
# End SUBSYSTEM LIBSAMBA3
|
||||
################################################
|
||||
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Unix SMB/CIFS implementation.
|
||||
* RPC Pipe client / server routines
|
||||
* Copyright (C) Andrew Tridgell 1992-2000,
|
||||
* Copyright (C) Jean François Micouleau 1998-2001.
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "lib/samba3/samba3.h"
|
||||
#include "lib/tdb/include/tdb.h"
|
||||
#include "lib/util/util_tdb.h"
|
||||
#include "system/filesys.h"
|
||||
#include "libcli/security/security.h"
|
||||
|
||||
#define DATABASE_VERSION_V1 1 /* native byte format. */
|
||||
#define DATABASE_VERSION_V2 2 /* le format. */
|
||||
|
||||
#define GROUP_PREFIX "UNIXGROUP/"
|
||||
|
||||
/* Alias memberships are stored reverse, as memberships. The performance
|
||||
* critical operation is to determine the aliases a SID is member of, not
|
||||
* listing alias members. So we store a list of alias SIDs a SID is member of
|
||||
* hanging of the member as key.
|
||||
*/
|
||||
#define MEMBEROF_PREFIX "MEMBEROF/"
|
||||
|
||||
/****************************************************************************
|
||||
Open the group mapping tdb.
|
||||
****************************************************************************/
|
||||
NTSTATUS samba3_read_grouptdb(const char *file, TALLOC_CTX *ctx, struct samba3_groupdb *db)
|
||||
{
|
||||
int32_t vers_id;
|
||||
TDB_DATA kbuf, dbuf, newkey;
|
||||
int ret;
|
||||
TDB_CONTEXT *tdb;
|
||||
|
||||
tdb = tdb_open(file, 0, TDB_DEFAULT, O_RDONLY, 0600);
|
||||
if (!tdb) {
|
||||
DEBUG(0,("Failed to open group mapping database\n"));
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
/* Cope with byte-reversed older versions of the db. */
|
||||
vers_id = tdb_fetch_int32(tdb, "INFO/version");
|
||||
if ((vers_id == DATABASE_VERSION_V1) || (IREV(vers_id) == DATABASE_VERSION_V1)) {
|
||||
/* Written on a bigendian machine with old fetch_int code. Save as le. */
|
||||
vers_id = DATABASE_VERSION_V2;
|
||||
}
|
||||
|
||||
if (vers_id != DATABASE_VERSION_V2) {
|
||||
DEBUG(0, ("Group database version mismatch: %d\n", vers_id));
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
db->groupmappings = NULL;
|
||||
db->groupmap_count = 0;
|
||||
db->aliases = NULL;
|
||||
db->alias_count = 0;
|
||||
|
||||
for (kbuf = tdb_firstkey(tdb);
|
||||
kbuf.dptr;
|
||||
newkey = tdb_nextkey(tdb, kbuf), free(kbuf.dptr), kbuf=newkey) {
|
||||
struct samba3_groupmapping map;
|
||||
const char *k = (const char *)kbuf.dptr;
|
||||
|
||||
if (strncmp(k, GROUP_PREFIX, strlen(GROUP_PREFIX)) == 0)
|
||||
{
|
||||
dbuf = tdb_fetch(tdb, kbuf);
|
||||
if (!dbuf.dptr)
|
||||
continue;
|
||||
|
||||
ZERO_STRUCT(map);
|
||||
|
||||
map.sid = dom_sid_parse_talloc(ctx, k+strlen(GROUP_PREFIX));
|
||||
|
||||
ret = tdb_unpack(tdb, (char *)dbuf.dptr, dbuf.dsize, "dd",
|
||||
&map.gid, &map.sid_name_use);
|
||||
|
||||
if ( ret == -1 ) {
|
||||
DEBUG(3,("enum_group_mapping: tdb_unpack failure\n"));
|
||||
continue;
|
||||
}
|
||||
|
||||
map.nt_name = talloc_strdup(ctx, (const char *)(dbuf.dptr+ret));
|
||||
map.comment = talloc_strdup(ctx, (const char *)(dbuf.dptr+ret+strlen(map.nt_name)));
|
||||
|
||||
db->groupmappings = talloc_realloc(ctx, db->groupmappings, struct samba3_groupmapping, db->groupmap_count+1);
|
||||
|
||||
if (!db->groupmappings)
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
|
||||
db->groupmappings[db->groupmap_count] = map;
|
||||
|
||||
db->groupmap_count++;
|
||||
} else if (strncmp(k, MEMBEROF_PREFIX, strlen(MEMBEROF_PREFIX)) == 0)
|
||||
{
|
||||
struct samba3_alias alias;
|
||||
const char **member_strlist;
|
||||
int i;
|
||||
|
||||
dbuf = tdb_fetch(tdb, kbuf);
|
||||
if (!dbuf.dptr)
|
||||
continue;
|
||||
|
||||
alias.sid = dom_sid_parse_talloc(ctx, k+strlen(MEMBEROF_PREFIX));
|
||||
alias.member_count = 0;
|
||||
alias.members = NULL;
|
||||
|
||||
member_strlist = str_list_make_shell(ctx, (const char *)dbuf.dptr, " ");
|
||||
|
||||
for (i = 0; member_strlist[i]; i++) {
|
||||
alias.members = talloc_realloc(ctx, alias.members, struct dom_sid *, alias.member_count+1);
|
||||
alias.members[alias.member_count] = dom_sid_parse_talloc(ctx, member_strlist[i]);
|
||||
alias.member_count++;
|
||||
}
|
||||
|
||||
talloc_free(member_strlist);
|
||||
|
||||
db->aliases = talloc_realloc(ctx, db->aliases, struct samba3_alias, db->alias_count+1);
|
||||
db->aliases[db->alias_count] = alias;
|
||||
db->alias_count++;
|
||||
}
|
||||
}
|
||||
|
||||
tdb_close(tdb);
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
|
||||
idmap TDB backend
|
||||
|
||||
Copyright (C) Tim Potter 2000
|
||||
Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
|
||||
Copyright (C) Simo Sorce 2003
|
||||
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
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "lib/tdb/include/tdb.h"
|
||||
#include "lib/util/util_tdb.h"
|
||||
#include "lib/samba3/samba3.h"
|
||||
#include "system/filesys.h"
|
||||
#include "libcli/security/security.h"
|
||||
|
||||
/* High water mark keys */
|
||||
#define HWM_GROUP "GROUP HWM"
|
||||
#define HWM_USER "USER HWM"
|
||||
|
||||
/* idmap version determines auto-conversion */
|
||||
#define IDMAP_VERSION 2
|
||||
|
||||
/*****************************************************************************
|
||||
Initialise idmap database.
|
||||
*****************************************************************************/
|
||||
|
||||
NTSTATUS samba3_read_idmap(const char *fn, TALLOC_CTX *ctx, struct samba3_idmapdb *idmap)
|
||||
{
|
||||
TDB_CONTEXT *tdb;
|
||||
TDB_DATA key, val;
|
||||
int32_t version;
|
||||
|
||||
/* Open idmap repository */
|
||||
if (!(tdb = tdb_open(fn, 0, TDB_DEFAULT, O_RDONLY, 0644))) {
|
||||
DEBUG(0, ("idmap_init: Unable to open idmap database '%s'\n", fn));
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
idmap->mapping_count = 0;
|
||||
idmap->mappings = NULL;
|
||||
idmap->user_hwm = tdb_fetch_int32(tdb, HWM_USER);
|
||||
idmap->group_hwm = tdb_fetch_int32(tdb, HWM_GROUP);
|
||||
|
||||
/* check against earlier versions */
|
||||
version = tdb_fetch_int32(tdb, "IDMAP_VERSION");
|
||||
if (version != IDMAP_VERSION) {
|
||||
DEBUG(0, ("idmap_init: Unable to open idmap database, it's in an old format!\n"));
|
||||
return NT_STATUS_INTERNAL_DB_ERROR;
|
||||
}
|
||||
|
||||
for (key = tdb_firstkey(tdb); key.dptr; key = tdb_nextkey(tdb, key))
|
||||
{
|
||||
struct samba3_idmap_mapping map;
|
||||
const char *k = (const char *)key.dptr;
|
||||
const char *v;
|
||||
|
||||
if (strncmp(k, "GID ", 4) == 0) {
|
||||
map.type = IDMAP_GROUP;
|
||||
map.unix_id = atoi(k+4);
|
||||
val = tdb_fetch(tdb, key);
|
||||
v = (const char *)val.dptr;
|
||||
map.sid = dom_sid_parse_talloc(ctx, v);
|
||||
} else if (strncmp(k, "UID ", 4) == 0) {
|
||||
map.type = IDMAP_USER;
|
||||
map.unix_id = atoi(k+4);
|
||||
val = tdb_fetch(tdb, key);
|
||||
v = (const char *)val.dptr;
|
||||
map.sid = dom_sid_parse_talloc(ctx, v);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
idmap->mappings = talloc_realloc(ctx, idmap->mappings, struct samba3_idmap_mapping, idmap->mapping_count+1);
|
||||
|
||||
idmap->mappings[idmap->mapping_count] = map;
|
||||
idmap->mapping_count++;
|
||||
}
|
||||
|
||||
tdb_close(tdb);
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Unix SMB/CIFS implementation.
|
||||
* account policy storage
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "lib/tdb/include/tdb.h"
|
||||
#include "lib/util/util_tdb.h"
|
||||
#include "lib/samba3/samba3.h"
|
||||
#include "system/filesys.h"
|
||||
|
||||
NTSTATUS samba3_read_account_policy(const char *fn, TALLOC_CTX *ctx, struct samba3_policy *ret)
|
||||
{
|
||||
TDB_CONTEXT *tdb = tdb_open(fn, 0, TDB_DEFAULT, O_RDONLY, 0600);
|
||||
if (!tdb) {
|
||||
DEBUG(0,("Failed to open account policy database\n"));
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
tdb_fetch_uint32(tdb, "min password length", &ret->min_password_length);
|
||||
tdb_fetch_uint32(tdb, "password history", &ret->password_history);
|
||||
tdb_fetch_uint32(tdb, "user must logon to change pasword", &ret->user_must_logon_to_change_password);
|
||||
tdb_fetch_uint32(tdb, "maximum password age", &ret->maximum_password_age);
|
||||
tdb_fetch_uint32(tdb, "minimum password age", &ret->minimum_password_age);
|
||||
tdb_fetch_uint32(tdb, "lockout duration", &ret->lockout_duration);
|
||||
tdb_fetch_uint32(tdb, "reset count minutes", &ret->reset_count_minutes);
|
||||
tdb_fetch_uint32(tdb, "bad lockout minutes", &ret->bad_lockout_minutes);
|
||||
tdb_fetch_uint32(tdb, "disconnect time", &ret->disconnect_time);
|
||||
tdb_fetch_uint32(tdb, "refuse machine password change", &ret->refuse_machine_password_change);
|
||||
|
||||
/* FIXME: Read privileges as well */
|
||||
|
||||
tdb_close(tdb);
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Unix SMB/CIFS implementation.
|
||||
* Virtual Windows Registry Layer
|
||||
* Copyright (C) Gerald Carter 2002-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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* Implementation of internal registry database functions. */
|
||||
|
||||
#include "includes.h"
|
||||
#include "lib/samba3/samba3.h"
|
||||
#include "librpc/gen_ndr/winreg.h"
|
||||
#include "lib/tdb/include/tdb.h"
|
||||
#include "lib/util/util_tdb.h"
|
||||
#include "system/filesys.h"
|
||||
#include "pstring.h"
|
||||
|
||||
#define VALUE_PREFIX "SAMBA_REGVAL"
|
||||
#define REGVER_V1 1 /* first db version with write support */
|
||||
|
||||
/****************************************************************************
|
||||
Unpack a list of registry values from the TDB
|
||||
***************************************************************************/
|
||||
|
||||
static int regdb_unpack_values(TDB_CONTEXT *tdb, TALLOC_CTX *ctx, struct samba3_regkey *key, TDB_DATA data )
|
||||
{
|
||||
int len = 0;
|
||||
uint32_t type;
|
||||
uint32_t size;
|
||||
uint8_t *data_p;
|
||||
uint32_t num_values = 0;
|
||||
int i;
|
||||
fstring valuename;
|
||||
|
||||
/* loop and unpack the rest of the registry values */
|
||||
|
||||
len += tdb_unpack(tdb, (char *)data.dptr+len, data.dsize-len, "d", &num_values);
|
||||
|
||||
for ( i=0; i<num_values; i++ ) {
|
||||
struct samba3_regval val;
|
||||
/* unpack the next regval */
|
||||
|
||||
type = REG_NONE;
|
||||
size = 0;
|
||||
data_p = NULL;
|
||||
len += tdb_unpack(tdb, (char *)data.dptr+len, data.dsize-len, "fdB",
|
||||
valuename,
|
||||
&val.type,
|
||||
&size,
|
||||
&data_p);
|
||||
val.name = talloc_strdup(ctx, valuename);
|
||||
val.data = data_blob_talloc(ctx, data_p, size);
|
||||
|
||||
key->values = talloc_realloc(ctx, key->values, struct samba3_regval, key->value_count+1);
|
||||
key->values[key->value_count] = val;
|
||||
key->value_count++;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
Open the registry database
|
||||
***********************************************************************/
|
||||
|
||||
NTSTATUS samba3_read_regdb ( const char *fn, TALLOC_CTX *ctx, struct samba3_regdb *db )
|
||||
{
|
||||
uint32_t vers_id;
|
||||
TDB_CONTEXT *tdb;
|
||||
TDB_DATA kbuf, vbuf;
|
||||
|
||||
/* placeholder tdb; reinit upon startup */
|
||||
|
||||
if ( !(tdb = tdb_open(fn, 0, TDB_DEFAULT, O_RDONLY, 0600)) )
|
||||
{
|
||||
DEBUG(0, ("Unable to open registry database %s\n", fn));
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
vers_id = tdb_fetch_int32(tdb, "INFO/version");
|
||||
|
||||
db->key_count = 0;
|
||||
db->keys = NULL;
|
||||
|
||||
if (vers_id != -1 && vers_id >= REGVER_V1) {
|
||||
DEBUG(0, ("Registry version mismatch: %d\n", vers_id));
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
for (kbuf = tdb_firstkey(tdb); kbuf.dptr; kbuf = tdb_nextkey(tdb, kbuf))
|
||||
{
|
||||
uint32_t len;
|
||||
int i;
|
||||
struct samba3_regkey key;
|
||||
char *skey;
|
||||
|
||||
if (strncmp((char *)kbuf.dptr, VALUE_PREFIX, strlen(VALUE_PREFIX)) == 0)
|
||||
continue;
|
||||
|
||||
vbuf = tdb_fetch(tdb, kbuf);
|
||||
|
||||
key.name = talloc_strdup(ctx, (char *)kbuf.dptr);
|
||||
|
||||
len = tdb_unpack(tdb, (char *)vbuf.dptr, vbuf.dsize, "d", &key.subkey_count);
|
||||
|
||||
key.value_count = 0;
|
||||
key.values = NULL;
|
||||
key.subkeys = talloc_array(ctx, char *, key.subkey_count);
|
||||
|
||||
for (i = 0; i < key.subkey_count; i++) {
|
||||
fstring tmp;
|
||||
len += tdb_unpack( tdb, (char *)vbuf.dptr+len, vbuf.dsize-len, "f", tmp );
|
||||
key.subkeys[i] = talloc_strdup(ctx, tmp);
|
||||
}
|
||||
|
||||
skey = talloc_asprintf(ctx, "%s/%s", VALUE_PREFIX, kbuf.dptr );
|
||||
|
||||
vbuf = tdb_fetch_bystring( tdb, skey );
|
||||
|
||||
if ( vbuf.dptr ) {
|
||||
regdb_unpack_values( tdb, ctx, &key, vbuf );
|
||||
}
|
||||
|
||||
db->keys = talloc_realloc(ctx, db->keys, struct samba3_regkey, db->key_count+1);
|
||||
db->keys[db->key_count] = key;
|
||||
db->key_count++;
|
||||
}
|
||||
|
||||
tdb_close(tdb);
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Unix SMB/CIFS implementation.
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "lib/samba3/samba3.h"
|
||||
|
||||
struct samba3_domainsecrets *samba3_find_domainsecrets(struct samba3 *db, const char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < db->secrets.domain_count; i++) {
|
||||
if (!strcasecmp_m(db->secrets.domains[i].name, name))
|
||||
return &db->secrets.domains[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NTSTATUS samba3_read_passdb_backends(TALLOC_CTX *ctx, const char *libdir, struct samba3 *samba3)
|
||||
{
|
||||
char *dbfile;
|
||||
NTSTATUS status = NT_STATUS_OK;
|
||||
int i;
|
||||
const char **backends = param_get_string_list(samba3->configuration, NULL, "passdb backend", NULL);
|
||||
|
||||
/* Default to smbpasswd */
|
||||
if (backends == NULL)
|
||||
backends = str_list_make(ctx, "smbpasswd", LIST_SEP);
|
||||
else
|
||||
backends = str_list_copy(ctx, backends);
|
||||
|
||||
|
||||
for (i = 0; backends[i]; i++) {
|
||||
if (!strncmp(backends[i], "tdbsam", strlen("tdbsam"))) {
|
||||
const char *p = strchr(backends[i], ':');
|
||||
if (p && p[1]) {
|
||||
dbfile = talloc_strdup(ctx, p+1);
|
||||
} else {
|
||||
dbfile = talloc_asprintf(ctx, "%s/passdb.tdb", libdir);
|
||||
}
|
||||
samba3_read_tdbsam(dbfile, ctx, &samba3->samaccounts, &samba3->samaccount_count);
|
||||
talloc_free(dbfile);
|
||||
} else if (!strncmp(backends[i], "smbpasswd", strlen("smbpasswd"))) {
|
||||
const char *p = strchr(backends[i], ':');
|
||||
if (p && p[1]) {
|
||||
dbfile = talloc_strdup(ctx, p+1);
|
||||
} else if ((p = param_get_string(samba3->configuration, NULL, "smb passwd file"))) {
|
||||
dbfile = talloc_strdup(ctx, p);
|
||||
} else {
|
||||
dbfile = talloc_strdup(ctx, "/etc/samba/smbpasswd");
|
||||
}
|
||||
|
||||
samba3_read_smbpasswd(dbfile, ctx, &samba3->samaccounts, &samba3->samaccount_count);
|
||||
talloc_free(dbfile);
|
||||
} else if (!strncmp(backends[i], "ldapsam", strlen("ldapsam"))) {
|
||||
/* Will use samba3sam mapping module */
|
||||
} else {
|
||||
DEBUG(0, ("Upgrade from %s database not supported", backends[i]));
|
||||
status = NT_STATUS_NOT_SUPPORTED;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
talloc_free(backends);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
NTSTATUS samba3_read(const char *libdir, const char *smbconf, TALLOC_CTX *ctx, struct samba3 **samba3)
|
||||
{
|
||||
struct samba3 *ret;
|
||||
char *dbfile = NULL;
|
||||
|
||||
ret = talloc_zero(ctx, struct samba3);
|
||||
|
||||
if (smbconf != NULL) {
|
||||
ret->configuration = param_init(ret);
|
||||
if (param_read(ret->configuration, smbconf) == -1) {
|
||||
talloc_free(ret);
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
}
|
||||
|
||||
dbfile = talloc_asprintf(ctx, "%s/account_policy.tdb", libdir);
|
||||
samba3_read_account_policy(dbfile, ctx, &ret->policy);
|
||||
talloc_free(dbfile);
|
||||
|
||||
dbfile = talloc_asprintf(ctx, "%s/registry.tdb", libdir);
|
||||
samba3_read_regdb(dbfile, ctx, &ret->registry);
|
||||
talloc_free(dbfile);
|
||||
|
||||
dbfile = talloc_asprintf(ctx, "%s/secrets.tdb", libdir);
|
||||
samba3_read_secrets(dbfile, ctx, &ret->secrets);
|
||||
talloc_free(dbfile);
|
||||
|
||||
dbfile = talloc_asprintf(ctx, "%s/share_info.tdb", libdir);
|
||||
samba3_read_share_info(dbfile, ctx, ret);
|
||||
talloc_free(dbfile);
|
||||
|
||||
dbfile = talloc_asprintf(ctx, "%s/winbindd_idmap.tdb", libdir);
|
||||
samba3_read_idmap(dbfile, ctx, &ret->idmap);
|
||||
talloc_free(dbfile);
|
||||
|
||||
dbfile = talloc_asprintf(ctx, "%s/wins.dat", libdir);
|
||||
samba3_read_winsdb(dbfile, ret, &ret->winsdb_entries, &ret->winsdb_count);
|
||||
talloc_free(dbfile);
|
||||
|
||||
samba3_read_passdb_backends(ctx, libdir, ret);
|
||||
|
||||
dbfile = talloc_asprintf(ctx, "%s/group_mapping.tdb", libdir);
|
||||
samba3_read_grouptdb(dbfile, ctx, &ret->group);
|
||||
talloc_free(dbfile);
|
||||
|
||||
*samba3 = ret;
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
@@ -0,0 +1,215 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
Samba3 interfaces
|
||||
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
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef _SAMBA3_H /* _SAMBA3_H */
|
||||
#define _SAMBA3_H
|
||||
|
||||
#include "librpc/gen_ndr/security.h"
|
||||
#include "librpc/gen_ndr/samr.h"
|
||||
#include "param/param.h"
|
||||
|
||||
struct samba3_samaccount {
|
||||
uint32_t logon_time,
|
||||
logoff_time,
|
||||
kickoff_time,
|
||||
bad_password_time,
|
||||
pass_last_set_time,
|
||||
pass_can_change_time,
|
||||
pass_must_change_time;
|
||||
char *username;
|
||||
char *domain;
|
||||
char *nt_username;
|
||||
char *dir_drive;
|
||||
char *unknown_str;
|
||||
char *munged_dial;
|
||||
char *fullname;
|
||||
char *homedir;
|
||||
char *logon_script;
|
||||
char *profile_path;
|
||||
char *acct_desc;
|
||||
char *workstations;
|
||||
uint32_t user_rid, group_rid, hours_len, unknown_6;
|
||||
uint16_t acct_ctrl, logon_divs;
|
||||
uint16_t bad_password_count, logon_count;
|
||||
struct samr_Password lm_pw, nt_pw;
|
||||
uint8_t *nt_pw_hist_ptr;
|
||||
uint8_t *hours;
|
||||
};
|
||||
|
||||
struct samba3_groupmapping {
|
||||
gid_t gid;
|
||||
struct dom_sid *sid;
|
||||
int sid_name_use;
|
||||
const char *nt_name;
|
||||
const char *comment;
|
||||
};
|
||||
|
||||
struct samba3_alias {
|
||||
struct dom_sid *sid;
|
||||
uint32_t member_count;
|
||||
struct dom_sid **members;
|
||||
};
|
||||
|
||||
struct samba3_groupdb {
|
||||
uint32_t groupmap_count;
|
||||
struct samba3_groupmapping *groupmappings;
|
||||
|
||||
uint32_t alias_count;
|
||||
struct samba3_alias *aliases;
|
||||
};
|
||||
|
||||
struct samba3_idmap_mapping
|
||||
{
|
||||
enum { IDMAP_GROUP, IDMAP_USER } type;
|
||||
uint32_t unix_id;
|
||||
struct dom_sid *sid;
|
||||
};
|
||||
|
||||
struct samba3_idmapdb
|
||||
{
|
||||
/* High water marks */
|
||||
uint32_t user_hwm;
|
||||
uint32_t group_hwm;
|
||||
|
||||
uint32_t mapping_count;
|
||||
struct samba3_idmap_mapping *mappings;
|
||||
};
|
||||
|
||||
struct samba3_winsdb_entry
|
||||
{
|
||||
char *name;
|
||||
int nb_flags;
|
||||
int type;
|
||||
time_t ttl;
|
||||
uint32_t ip_count;
|
||||
struct ipv4_addr *ips;
|
||||
};
|
||||
|
||||
struct samba3_policy
|
||||
{
|
||||
uint32_t min_password_length;
|
||||
uint32_t password_history;
|
||||
uint32_t user_must_logon_to_change_password;
|
||||
uint32_t maximum_password_age;
|
||||
uint32_t minimum_password_age;
|
||||
uint32_t lockout_duration;
|
||||
uint32_t reset_count_minutes;
|
||||
uint32_t bad_lockout_minutes;
|
||||
uint32_t disconnect_time;
|
||||
uint32_t refuse_machine_password_change;
|
||||
};
|
||||
|
||||
struct samba3_regval {
|
||||
char *name;
|
||||
uint16_t type;
|
||||
DATA_BLOB data;
|
||||
};
|
||||
|
||||
struct samba3_regkey {
|
||||
char *name;
|
||||
|
||||
uint32_t value_count;
|
||||
struct samba3_regval *values;
|
||||
|
||||
uint32_t subkey_count;
|
||||
char **subkeys;
|
||||
};
|
||||
|
||||
struct samba3_regdb
|
||||
{
|
||||
uint32_t key_count;
|
||||
struct samba3_regkey *keys;
|
||||
};
|
||||
|
||||
struct samba3_secrets
|
||||
{
|
||||
struct cli_credentials *ipc_cred;
|
||||
|
||||
uint32_t ldappw_count;
|
||||
struct samba3_ldappw
|
||||
{
|
||||
char *dn;
|
||||
char *password;
|
||||
} *ldappws;
|
||||
|
||||
uint32_t domain_count;
|
||||
struct samba3_domainsecrets
|
||||
{
|
||||
char *name;
|
||||
struct dom_sid sid;
|
||||
struct GUID guid;
|
||||
char *plaintext_pw;
|
||||
time_t last_change_time;
|
||||
struct {
|
||||
uint8_t hash[16];
|
||||
time_t mod_time;
|
||||
} hash_pw;
|
||||
int sec_channel_type;
|
||||
} *domains;
|
||||
|
||||
uint32_t trusted_domain_count;
|
||||
struct samba3_trusted_dom_pass {
|
||||
uint32_t uni_name_len;
|
||||
const char *uni_name[32]; /* unicode domain name */
|
||||
const char *pass; /* trust relationship's password */
|
||||
time_t mod_time;
|
||||
struct dom_sid domain_sid; /* remote domain's sid */
|
||||
} *trusted_domains;
|
||||
|
||||
uint32_t afs_keyfile_count;
|
||||
|
||||
struct samba3_afs_keyfile {
|
||||
uint32_t nkeys;
|
||||
struct {
|
||||
uint32_t kvno;
|
||||
char key[8];
|
||||
} entry[8];
|
||||
char *cell;
|
||||
} *afs_keyfiles;
|
||||
};
|
||||
|
||||
struct samba3_share_info {
|
||||
char *name;
|
||||
struct security_descriptor secdesc;
|
||||
};
|
||||
|
||||
struct samba3
|
||||
{
|
||||
struct param_context *configuration;
|
||||
|
||||
uint32_t winsdb_count;
|
||||
struct samba3_winsdb_entry *winsdb_entries;
|
||||
|
||||
uint32_t samaccount_count;
|
||||
struct samba3_samaccount *samaccounts;
|
||||
|
||||
uint32_t share_count;
|
||||
struct samba3_share_info *shares;
|
||||
|
||||
struct samba3_secrets secrets;
|
||||
struct samba3_groupdb group;
|
||||
struct samba3_idmapdb idmap;
|
||||
struct samba3_policy policy;
|
||||
struct samba3_regdb registry;
|
||||
};
|
||||
|
||||
#include "lib/samba3/samba3_proto.h"
|
||||
|
||||
#endif /* _SAMBA3_H */
|
||||
@@ -0,0 +1,264 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
Copyright (C) Andrew Tridgell 1992-2001
|
||||
Copyright (C) Andrew Bartlett 2002
|
||||
Copyright (C) Rafal Szczesniak 2002
|
||||
Copyright (C) Tim Potter 2001
|
||||
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
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* the Samba secrets database stores any generated, private information
|
||||
such as the local SID and machine trust password */
|
||||
|
||||
#include "includes.h"
|
||||
#include "lib/tdb/include/tdb.h"
|
||||
#include "lib/util/util_tdb.h"
|
||||
#include "lib/samba3/samba3.h"
|
||||
#include "system/filesys.h"
|
||||
#include "librpc/gen_ndr/security.h"
|
||||
#include "auth/credentials/credentials.h"
|
||||
|
||||
/**
|
||||
* Unpack SID into a pointer
|
||||
*
|
||||
* @param pack_buf pointer to buffer with packed representation
|
||||
* @param bufsize size of the buffer
|
||||
* @param sid pointer to sid structure to be filled with unpacked data
|
||||
*
|
||||
* @return size of structure unpacked from buffer
|
||||
**/
|
||||
static size_t tdb_sid_unpack(TDB_CONTEXT *tdb, char* pack_buf, int bufsize, struct dom_sid* sid)
|
||||
{
|
||||
int idx, len = 0;
|
||||
|
||||
if (!sid || !pack_buf) return -1;
|
||||
|
||||
len += tdb_unpack(tdb, pack_buf + len, bufsize - len, "bb",
|
||||
&sid->sid_rev_num, &sid->num_auths);
|
||||
|
||||
for (idx = 0; idx < 6; idx++) {
|
||||
len += tdb_unpack(tdb, pack_buf + len, bufsize - len, "b", &sid->id_auth[idx]);
|
||||
}
|
||||
|
||||
for (idx = 0; idx < 15; idx++) {
|
||||
len += tdb_unpack(tdb, pack_buf + len, bufsize - len, "d", &sid->sub_auths[idx]);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static struct samba3_domainsecrets *secrets_find_domain(TALLOC_CTX *ctx, struct samba3_secrets *db, const char *key)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < db->domain_count; i++)
|
||||
{
|
||||
if (!strcasecmp_m(db->domains[i].name, key))
|
||||
return &db->domains[i];
|
||||
}
|
||||
|
||||
db->domains = talloc_realloc(ctx, db->domains, struct samba3_domainsecrets, db->domain_count+1);
|
||||
ZERO_STRUCT(db->domains[db->domain_count]);
|
||||
db->domains[db->domain_count].name = talloc_strdup(db->domains, key);
|
||||
|
||||
db->domain_count++;
|
||||
|
||||
return &db->domains[db->domain_count-1];
|
||||
}
|
||||
|
||||
static NTSTATUS ipc_password (TDB_CONTEXT *tdb, const char *key, TDB_DATA vbuf, TALLOC_CTX *ctx, struct samba3_secrets *db)
|
||||
{
|
||||
cli_credentials_set_password(db->ipc_cred, (const char *)vbuf.dptr, CRED_SPECIFIED);
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
static NTSTATUS ipc_username (TDB_CONTEXT *tdb, const char *key, TDB_DATA vbuf, TALLOC_CTX *ctx, struct samba3_secrets *db)
|
||||
{
|
||||
cli_credentials_set_username(db->ipc_cred, (const char *)vbuf.dptr, CRED_SPECIFIED);
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
static NTSTATUS ipc_domain (TDB_CONTEXT *tdb, const char *key, TDB_DATA vbuf, TALLOC_CTX *ctx, struct samba3_secrets *db)
|
||||
{
|
||||
cli_credentials_set_domain(db->ipc_cred, (const char *)vbuf.dptr, CRED_SPECIFIED);
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
static NTSTATUS domain_sid (TDB_CONTEXT *tdb, const char *key, TDB_DATA vbuf, TALLOC_CTX *ctx, struct samba3_secrets *db)
|
||||
{
|
||||
struct samba3_domainsecrets *domainsec = secrets_find_domain(ctx, db, key);
|
||||
domainsec->sid.sub_auths = talloc_array(ctx, uint32_t, 15);
|
||||
tdb_sid_unpack(tdb, (char *)vbuf.dptr, vbuf.dsize, &domainsec->sid);
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
static NTSTATUS domain_guid (TDB_CONTEXT *tdb, const char *key, TDB_DATA vbuf, TALLOC_CTX *ctx, struct samba3_secrets *db)
|
||||
{
|
||||
struct samba3_domainsecrets *domainsec = secrets_find_domain(ctx, db, key);
|
||||
memcpy(&domainsec->guid, vbuf.dptr, vbuf.dsize);
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
static NTSTATUS ldap_bind_pw (TDB_CONTEXT *tdb, const char *key, TDB_DATA vbuf, TALLOC_CTX *ctx, struct samba3_secrets *db)
|
||||
{
|
||||
struct samba3_ldappw pw;
|
||||
pw.dn = talloc_strdup(ctx, key);
|
||||
pw.password = talloc_strdup(ctx, (const char *)vbuf.dptr);
|
||||
|
||||
db->ldappws = talloc_realloc(ctx, db->ldappws, struct samba3_ldappw, db->ldappw_count+1);
|
||||
db->ldappws[db->ldappw_count] = pw;
|
||||
db->ldappw_count++;
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
static NTSTATUS afs_keyfile (TDB_CONTEXT *tdb, const char *key, TDB_DATA vbuf, TALLOC_CTX *ctx, struct samba3_secrets *db)
|
||||
{
|
||||
struct samba3_afs_keyfile keyfile;
|
||||
memcpy(&keyfile, vbuf.dptr, vbuf.dsize);
|
||||
keyfile.cell = talloc_strdup(ctx, key);
|
||||
|
||||
db->afs_keyfiles = talloc_realloc(ctx, db->afs_keyfiles, struct samba3_afs_keyfile, db->afs_keyfile_count+1);
|
||||
db->afs_keyfiles[db->afs_keyfile_count] = keyfile;
|
||||
db->afs_keyfile_count++;
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
static NTSTATUS machine_sec_channel_type (TDB_CONTEXT *tdb, const char *key, TDB_DATA vbuf, TALLOC_CTX *ctx, struct samba3_secrets *db)
|
||||
{
|
||||
struct samba3_domainsecrets *domainsec = secrets_find_domain(ctx, db, key);
|
||||
|
||||
domainsec->sec_channel_type = IVAL(vbuf.dptr, 0);
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
static NTSTATUS machine_last_change_time (TDB_CONTEXT *tdb, const char *key, TDB_DATA vbuf, TALLOC_CTX *ctx, struct samba3_secrets *db)
|
||||
{
|
||||
struct samba3_domainsecrets *domainsec = secrets_find_domain(ctx, db, key);
|
||||
domainsec->last_change_time = IVAL(vbuf.dptr, 0);
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
static NTSTATUS machine_password (TDB_CONTEXT *tdb, const char *key, TDB_DATA vbuf, TALLOC_CTX *ctx, struct samba3_secrets *db)
|
||||
{
|
||||
struct samba3_domainsecrets *domainsec = secrets_find_domain(ctx, db, key);
|
||||
domainsec->plaintext_pw = talloc_strdup(ctx, (const char *)vbuf.dptr);
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
static NTSTATUS machine_acc (TDB_CONTEXT *tdb, const char *key, TDB_DATA vbuf, TALLOC_CTX *ctx, struct samba3_secrets *db)
|
||||
{
|
||||
struct samba3_domainsecrets *domainsec = secrets_find_domain(ctx, db, key);
|
||||
|
||||
memcpy(&domainsec->hash_pw, vbuf.dptr, vbuf.dsize);
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
static NTSTATUS random_seed (TDB_CONTEXT *tdb, const char *key, TDB_DATA vbuf, TALLOC_CTX *ctx, struct samba3_secrets *db)
|
||||
{
|
||||
/* Ignore */
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
static NTSTATUS domtrust_acc (TDB_CONTEXT *tdb, const char *key, TDB_DATA vbuf, TALLOC_CTX *ctx, struct samba3_secrets *db)
|
||||
{
|
||||
int idx, len = 0;
|
||||
struct samba3_trusted_dom_pass pass;
|
||||
int pass_len;
|
||||
|
||||
if (!vbuf.dptr)
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
|
||||
/* unpack unicode domain name and plaintext password */
|
||||
len += tdb_unpack(tdb, (char *)vbuf.dptr, vbuf.dsize - len, "d", &pass.uni_name_len);
|
||||
|
||||
for (idx = 0; idx < 32; idx++)
|
||||
len += tdb_unpack(tdb, (char *)(vbuf.dptr + len), vbuf.dsize - len, "w", &pass.uni_name[idx]);
|
||||
|
||||
len += tdb_unpack(tdb, (char *)(vbuf.dptr + len), vbuf.dsize - len, "d", &pass_len);
|
||||
pass.pass = talloc_strdup(ctx, (char *)(vbuf.dptr+len));
|
||||
len += strlen((const char *)vbuf.dptr)+1;
|
||||
len += tdb_unpack(tdb, (char *)(vbuf.dptr + len), vbuf.dsize - len, "d", &pass.mod_time);
|
||||
|
||||
pass.domain_sid.sub_auths = talloc_array(ctx, uint32_t, 15);
|
||||
/* unpack domain sid */
|
||||
len += tdb_sid_unpack(tdb, (char *)(vbuf.dptr + len), vbuf.dsize - len, &pass.domain_sid);
|
||||
|
||||
/* FIXME: Add to list */
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
static const struct {
|
||||
const char *prefix;
|
||||
NTSTATUS (*handler) (TDB_CONTEXT *tdb, const char *key, TDB_DATA vbuf, TALLOC_CTX *ctx, struct samba3_secrets *db);
|
||||
} secrets_handlers[] = {
|
||||
{ "SECRETS/AUTH_PASSWORD", ipc_password },
|
||||
{ "SECRETS/AUTH_DOMAIN", ipc_domain },
|
||||
{ "SECRETS/AUTH_USER", ipc_username },
|
||||
{ "SECRETS/SID/", domain_sid },
|
||||
{ "SECRETS/DOMGUID/", domain_guid },
|
||||
{ "SECRETS/LDAP_BIND_PW/", ldap_bind_pw },
|
||||
{ "SECRETS/AFS_KEYFILE/", afs_keyfile },
|
||||
{ "SECRETS/MACHINE_SEC_CHANNEL_TYPE/", machine_sec_channel_type },
|
||||
{ "SECRETS/MACHINE_LAST_CHANGE_TIME/", machine_last_change_time },
|
||||
{ "SECRETS/MACHINE_PASSWORD/", machine_password },
|
||||
{ "SECRETS/$MACHINE.ACC/", machine_acc },
|
||||
{ "SECRETS/$DOMTRUST.ACC/", domtrust_acc },
|
||||
{ "INFO/random_seed", random_seed },
|
||||
};
|
||||
|
||||
|
||||
NTSTATUS samba3_read_secrets(const char *fname, TALLOC_CTX *ctx, struct samba3_secrets *db)
|
||||
{
|
||||
TDB_CONTEXT *tdb = tdb_open(fname, 0, TDB_DEFAULT, O_RDONLY, 0600);
|
||||
TDB_DATA kbuf, vbuf;
|
||||
|
||||
if (!tdb) {
|
||||
DEBUG(0,("Failed to open %s\n", fname));
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
ZERO_STRUCTP(db);
|
||||
|
||||
db->ipc_cred = cli_credentials_init(ctx);
|
||||
|
||||
for (kbuf = tdb_firstkey(tdb); kbuf.dptr; kbuf = tdb_nextkey(tdb, kbuf))
|
||||
{
|
||||
int i;
|
||||
char *key;
|
||||
vbuf = tdb_fetch(tdb, kbuf);
|
||||
|
||||
for (i = 0; secrets_handlers[i].prefix; i++) {
|
||||
if (!strncmp((const char *)kbuf.dptr, secrets_handlers[i].prefix, strlen(secrets_handlers[i].prefix))) {
|
||||
key = talloc_strndup(ctx, (const char *)(kbuf.dptr+strlen(secrets_handlers[i].prefix)), kbuf.dsize-strlen(secrets_handlers[i].prefix));
|
||||
secrets_handlers[i].handler(tdb, key, vbuf, ctx, db);
|
||||
talloc_free(key);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!secrets_handlers[i].prefix) {
|
||||
DEBUG(0, ("Unable to find handler for string %s\n", kbuf.dptr));
|
||||
}
|
||||
}
|
||||
|
||||
tdb_close(tdb);
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Unix SMB/CIFS implementation.
|
||||
* Share Info parsing
|
||||
* Copyright (C) Andrew Tridgell 1992-1997,
|
||||
* Copyright (C) Jeremy Allison 2001.
|
||||
* Copyright (C) Nigel Williams 2001.
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "librpc/gen_ndr/ndr_security.h"
|
||||
#include "lib/tdb/include/tdb.h"
|
||||
#include "lib/util/util_tdb.h"
|
||||
#include "lib/samba3/samba3.h"
|
||||
#include "system/filesys.h"
|
||||
|
||||
#define SHARE_DATABASE_VERSION_V1 1
|
||||
#define SHARE_DATABASE_VERSION_V2 2 /* version id in little endian. */
|
||||
|
||||
NTSTATUS samba3_read_share_info(const char *fn, TALLOC_CTX *ctx, struct samba3 *db)
|
||||
{
|
||||
int32_t vers_id;
|
||||
TDB_CONTEXT *tdb;
|
||||
TDB_DATA kbuf, vbuf;
|
||||
DATA_BLOB blob;
|
||||
|
||||
tdb = tdb_open(fn, 0, TDB_DEFAULT, O_RDONLY, 0600);
|
||||
if (!tdb) {
|
||||
DEBUG(0,("Failed to open share info database %s (%s)\n",
|
||||
fn, strerror(errno) ));
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
/* Cope with byte-reversed older versions of the db. */
|
||||
vers_id = tdb_fetch_int32(tdb, "INFO/version");
|
||||
if ((vers_id == SHARE_DATABASE_VERSION_V1) || (IREV(vers_id) == SHARE_DATABASE_VERSION_V1)) {
|
||||
/* Written on a bigendian machine with old fetch_int code. Save as le. */
|
||||
vers_id = SHARE_DATABASE_VERSION_V2;
|
||||
}
|
||||
|
||||
if (vers_id != SHARE_DATABASE_VERSION_V2) {
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
for (kbuf = tdb_firstkey(tdb); kbuf.dptr; kbuf = tdb_nextkey(tdb, kbuf))
|
||||
{
|
||||
struct ndr_pull *pull;
|
||||
struct samba3_share_info *share;
|
||||
char *name;
|
||||
|
||||
if (strncmp((char *)kbuf.dptr, "SECDESC/", strlen("SECDESC/")) != 0)
|
||||
continue;
|
||||
|
||||
name = talloc_strndup(ctx, (char *)kbuf.dptr+strlen("SECDESC/"), kbuf.dsize-strlen("SECDESC/"));
|
||||
|
||||
db->shares = talloc_realloc(db, db->shares, struct samba3_share_info, db->share_count+1);
|
||||
share = &db->shares[db->share_count];
|
||||
db->share_count++;
|
||||
|
||||
share->name = talloc_strdup(db, name);
|
||||
|
||||
vbuf = tdb_fetch(tdb, kbuf);
|
||||
blob.data = (uint8_t *)vbuf.dptr;
|
||||
blob.length = vbuf.dsize;
|
||||
|
||||
pull = ndr_pull_init_blob(&blob, ctx);
|
||||
|
||||
ndr_pull_security_descriptor(pull, NDR_SCALARS|NDR_BUFFERS, &share->secdesc);
|
||||
|
||||
talloc_free(pull);
|
||||
}
|
||||
|
||||
tdb_close(tdb);
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
@@ -0,0 +1,347 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
smbpasswd file format routines
|
||||
|
||||
Copyright (C) Andrew Tridgell 1992-1998
|
||||
Modified by Jeremy Allison 1995.
|
||||
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
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*! \file lib/smbpasswd.c
|
||||
|
||||
The smbpasswd file is used to store encrypted passwords in a similar
|
||||
fashion to the /etc/passwd file. The format is colon separated fields
|
||||
with one user per line like so:
|
||||
|
||||
<username>:<uid>:<lanman hash>:<nt hash>:<acb info>:<last change time>
|
||||
|
||||
The username and uid must correspond to an entry in the /etc/passwd
|
||||
file. The lanman and nt password hashes are 32 hex digits corresponding
|
||||
to the 16-byte lanman and nt hashes respectively.
|
||||
|
||||
The password last change time is stored as a string of the format
|
||||
LCD-<change time> where the change time is expressed as an
|
||||
|
||||
'N' No password
|
||||
'D' Disabled
|
||||
'H' Homedir required
|
||||
'T' Temp account.
|
||||
'U' User account (normal)
|
||||
'M' MNS logon user account - what is this ?
|
||||
'W' Workstation account
|
||||
'S' Server account
|
||||
'L' Locked account
|
||||
'X' No Xpiry on password
|
||||
'I' Interdomain trust account
|
||||
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "system/locale.h"
|
||||
#include "lib/samba3/samba3.h"
|
||||
|
||||
/*! Convert 32 hex characters into a 16 byte array. */
|
||||
|
||||
struct samr_Password *smbpasswd_gethexpwd(TALLOC_CTX *mem_ctx, const char *p)
|
||||
{
|
||||
int i;
|
||||
unsigned char lonybble, hinybble;
|
||||
const char *hexchars = "0123456789ABCDEF";
|
||||
const char *p1, *p2;
|
||||
struct samr_Password *pwd = talloc(mem_ctx, struct samr_Password);
|
||||
|
||||
if (!p) return NULL;
|
||||
|
||||
for (i = 0; i < (sizeof(pwd->hash) * 2); i += 2)
|
||||
{
|
||||
hinybble = toupper(p[i]);
|
||||
lonybble = toupper(p[i + 1]);
|
||||
|
||||
p1 = strchr_m(hexchars, hinybble);
|
||||
p2 = strchr_m(hexchars, lonybble);
|
||||
|
||||
if (!p1 || !p2) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hinybble = PTR_DIFF(p1, hexchars);
|
||||
lonybble = PTR_DIFF(p2, hexchars);
|
||||
|
||||
pwd->hash[i / 2] = (hinybble << 4) | lonybble;
|
||||
}
|
||||
return pwd;
|
||||
}
|
||||
|
||||
/*! Convert a 16-byte array into 32 hex characters. */
|
||||
struct samr_Password *lm_hash_p = NULL;
|
||||
struct samr_Password *nt_hash_p = NULL;
|
||||
|
||||
char *smbpasswd_sethexpwd(TALLOC_CTX *mem_ctx, struct samr_Password *pwd, uint16_t acb_info)
|
||||
{
|
||||
char *p;
|
||||
if (pwd != NULL) {
|
||||
int i;
|
||||
p = talloc_array(mem_ctx, char, 33);
|
||||
if (!p) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < sizeof(pwd->hash); i++)
|
||||
slprintf(&p[i*2], 3, "%02X", pwd->hash[i]);
|
||||
} else {
|
||||
if (acb_info & ACB_PWNOTREQ)
|
||||
p = talloc_strdup(mem_ctx, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX");
|
||||
else
|
||||
p = talloc_strdup(mem_ctx, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
/*! Decode the account control bits (ACB) info from a string. */
|
||||
|
||||
uint16_t smbpasswd_decode_acb_info(const char *p)
|
||||
{
|
||||
uint16_t acb_info = 0;
|
||||
BOOL finished = False;
|
||||
|
||||
/*
|
||||
* Check if the account type bits have been encoded after the
|
||||
* NT password (in the form [NDHTUWSLXI]).
|
||||
*/
|
||||
|
||||
if (*p != '[') return 0;
|
||||
|
||||
for (p++; *p && !finished; p++)
|
||||
{
|
||||
switch (*p) {
|
||||
case 'N': /* 'N'o password. */
|
||||
acb_info |= ACB_PWNOTREQ;
|
||||
break;
|
||||
case 'D': /* 'D'isabled. */
|
||||
acb_info |= ACB_DISABLED;
|
||||
break;
|
||||
case 'H': /* 'H'omedir required. */
|
||||
acb_info |= ACB_HOMDIRREQ;
|
||||
break;
|
||||
case 'T': /* 'T'emp account. */
|
||||
acb_info |= ACB_TEMPDUP;
|
||||
break;
|
||||
case 'U': /* 'U'ser account (normal). */
|
||||
acb_info |= ACB_NORMAL;
|
||||
break;
|
||||
case 'M': /* 'M'NS logon user account. What is this ? */
|
||||
acb_info |= ACB_MNS;
|
||||
break;
|
||||
case 'W': /* 'W'orkstation account. */
|
||||
acb_info |= ACB_WSTRUST;
|
||||
break;
|
||||
case 'S': /* 'S'erver account. */
|
||||
acb_info |= ACB_SVRTRUST;
|
||||
break;
|
||||
case 'L': /* 'L'ocked account. */
|
||||
acb_info |= ACB_AUTOLOCK;
|
||||
break;
|
||||
case 'X': /* No 'X'piry on password */
|
||||
acb_info |= ACB_PWNOEXP;
|
||||
break;
|
||||
case 'I': /* 'I'nterdomain trust account. */
|
||||
acb_info |= ACB_DOMTRUST;
|
||||
break;
|
||||
|
||||
case ' ':
|
||||
break;
|
||||
case ':':
|
||||
case '\n':
|
||||
case '\0':
|
||||
case ']':
|
||||
default:
|
||||
finished = True;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return acb_info;
|
||||
}
|
||||
|
||||
/*! Encode account control bits (ACBs) into a string. */
|
||||
|
||||
char *smbpasswd_encode_acb_info(TALLOC_CTX *mem_ctx, uint16_t acb_info)
|
||||
{
|
||||
char *acct_str = talloc_array(mem_ctx, char, 35);
|
||||
size_t i = 0;
|
||||
|
||||
acct_str[i++] = '[';
|
||||
|
||||
if (acb_info & ACB_PWNOTREQ ) acct_str[i++] = 'N';
|
||||
if (acb_info & ACB_DISABLED ) acct_str[i++] = 'D';
|
||||
if (acb_info & ACB_HOMDIRREQ) acct_str[i++] = 'H';
|
||||
if (acb_info & ACB_TEMPDUP ) acct_str[i++] = 'T';
|
||||
if (acb_info & ACB_NORMAL ) acct_str[i++] = 'U';
|
||||
if (acb_info & ACB_MNS ) acct_str[i++] = 'M';
|
||||
if (acb_info & ACB_WSTRUST ) acct_str[i++] = 'W';
|
||||
if (acb_info & ACB_SVRTRUST ) acct_str[i++] = 'S';
|
||||
if (acb_info & ACB_AUTOLOCK ) acct_str[i++] = 'L';
|
||||
if (acb_info & ACB_PWNOEXP ) acct_str[i++] = 'X';
|
||||
if (acb_info & ACB_DOMTRUST ) acct_str[i++] = 'I';
|
||||
|
||||
acct_str[i++] = ']';
|
||||
acct_str[i++] = '\0';
|
||||
|
||||
return acct_str;
|
||||
}
|
||||
|
||||
NTSTATUS samba3_read_smbpasswd(const char *filename, TALLOC_CTX *ctx, struct samba3_samaccount **accounts, uint32_t *count)
|
||||
{
|
||||
int numlines;
|
||||
char **lines;
|
||||
int i;
|
||||
|
||||
*count = 0;
|
||||
*accounts = NULL;
|
||||
|
||||
lines = file_lines_load(filename, &numlines, ctx);
|
||||
|
||||
if (lines == NULL) {
|
||||
DEBUG(0, ("Unable to load lines from %s\n", filename));
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
*accounts = talloc_array(ctx, struct samba3_samaccount, numlines);
|
||||
|
||||
for (i = 0; i < numlines; i++) {
|
||||
char *p = lines[i], *q;
|
||||
uid_t uid;
|
||||
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;
|
||||
|
||||
uid = atoi(p);
|
||||
|
||||
/* uid is ignored here.. */
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -0,0 +1,264 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
tdb passdb backend format routines
|
||||
|
||||
Copyright (C) Simo Sorce 2000-2003
|
||||
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
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "system/filesys.h"
|
||||
#include "lib/tdb/include/tdb.h"
|
||||
#include "lib/util/util_tdb.h"
|
||||
#include "lib/samba3/samba3.h"
|
||||
|
||||
#define TDB_FORMAT_STRING_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd"
|
||||
#define TDB_FORMAT_STRING_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd"
|
||||
#define TDB_FORMAT_STRING_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd"
|
||||
#define TDBSAM_VERSION_STRING "INFO/version"
|
||||
|
||||
static BOOL init_sam_from_buffer_v0(TDB_CONTEXT *tdb, struct samba3_samaccount *sampass, TDB_DATA buf)
|
||||
{
|
||||
uint32_t username_len, domain_len, nt_username_len,
|
||||
dir_drive_len, unknown_str_len, munged_dial_len,
|
||||
fullname_len, homedir_len, logon_script_len,
|
||||
profile_path_len, acct_desc_len, workstations_len;
|
||||
|
||||
uint32_t remove_me;
|
||||
uint32_t len = 0;
|
||||
uint32_t lm_pw_len, nt_pw_len, hourslen;
|
||||
|
||||
if(sampass == NULL || buf.dptr == NULL) {
|
||||
DEBUG(0, ("init_sam_from_buffer_v0: NULL parameters found!\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
/* unpack the buffer into variables */
|
||||
len = tdb_unpack (tdb, (char *)buf.dptr, buf.dsize, TDB_FORMAT_STRING_V0,
|
||||
&sampass->logon_time, /* d */
|
||||
&sampass->logoff_time, /* d */
|
||||
&sampass->kickoff_time, /* d */
|
||||
&sampass->pass_last_set_time, /* d */
|
||||
&sampass->pass_can_change_time, /* d */
|
||||
&sampass->pass_must_change_time, /* d */
|
||||
&username_len, &sampass->username, /* B */
|
||||
&domain_len, &sampass->domain, /* B */
|
||||
&nt_username_len, &sampass->nt_username, /* B */
|
||||
&fullname_len, &sampass->fullname, /* B */
|
||||
&homedir_len, &sampass->homedir, /* B */
|
||||
&dir_drive_len, &sampass->dir_drive, /* B */
|
||||
&logon_script_len, &sampass->logon_script, /* B */
|
||||
&profile_path_len, &sampass->profile_path, /* B */
|
||||
&acct_desc_len, &sampass->acct_desc, /* B */
|
||||
&workstations_len, &sampass->workstations, /* B */
|
||||
&unknown_str_len, &sampass->unknown_str, /* B */
|
||||
&munged_dial_len, &sampass->munged_dial, /* B */
|
||||
&sampass->user_rid, /* d */
|
||||
&sampass->group_rid, /* d */
|
||||
&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 */
|
||||
&sampass->hours_len, /* d */
|
||||
&hourslen, &sampass->hours, /* B */
|
||||
&sampass->bad_password_count, /* w */
|
||||
&sampass->logon_count, /* w */
|
||||
&sampass->unknown_6); /* d */
|
||||
|
||||
if (len == (uint32_t) -1) {
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
static BOOL init_sam_from_buffer_v1(TDB_CONTEXT *tdb, struct samba3_samaccount *sampass, TDB_DATA buf)
|
||||
{
|
||||
uint32_t username_len, domain_len, nt_username_len,
|
||||
dir_drive_len, unknown_str_len, munged_dial_len,
|
||||
fullname_len, homedir_len, logon_script_len,
|
||||
profile_path_len, acct_desc_len, workstations_len;
|
||||
|
||||
uint32_t remove_me;
|
||||
uint32_t len = 0;
|
||||
uint32_t lm_pw_len, nt_pw_len, hourslen;
|
||||
|
||||
if(sampass == NULL || buf.dptr == NULL) {
|
||||
DEBUG(0, ("init_sam_from_buffer_v1: NULL parameters found!\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
/* unpack the buffer into variables */
|
||||
len = tdb_unpack (tdb, (char *)buf.dptr, buf.dsize, TDB_FORMAT_STRING_V1,
|
||||
&sampass->logon_time, /* d */
|
||||
&sampass->logoff_time, /* d */
|
||||
&sampass->kickoff_time, /* d */
|
||||
/* Change from V0 is addition of bad_password_time field. */
|
||||
&sampass->bad_password_time, /* d */
|
||||
&sampass->pass_last_set_time, /* d */
|
||||
&sampass->pass_can_change_time, /* d */
|
||||
&sampass->pass_must_change_time, /* d */
|
||||
&username_len, &sampass->username, /* B */
|
||||
&domain_len, &sampass->domain, /* B */
|
||||
&nt_username_len, &sampass->nt_username, /* B */
|
||||
&fullname_len, &sampass->fullname, /* B */
|
||||
&homedir_len, &sampass->homedir, /* B */
|
||||
&dir_drive_len, &sampass->dir_drive, /* B */
|
||||
&logon_script_len, &sampass->logon_script, /* B */
|
||||
&profile_path_len, &sampass->profile_path, /* B */
|
||||
&acct_desc_len, &sampass->acct_desc, /* B */
|
||||
&workstations_len, &sampass->workstations, /* B */
|
||||
&unknown_str_len, &sampass->unknown_str, /* B */
|
||||
&munged_dial_len, &sampass->munged_dial, /* B */
|
||||
&sampass->user_rid, /* d */
|
||||
&sampass->group_rid, /* d */
|
||||
&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 */
|
||||
&sampass->hours_len, /* d */
|
||||
&hourslen, &sampass->hours, /* B */
|
||||
&sampass->bad_password_count, /* w */
|
||||
&sampass->logon_count, /* w */
|
||||
&sampass->unknown_6); /* d */
|
||||
|
||||
if (len == (uint32_t) -1) {
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
static BOOL init_sam_from_buffer_v2(TDB_CONTEXT *tdb, struct samba3_samaccount *sampass, TDB_DATA buf)
|
||||
{
|
||||
uint32_t username_len, domain_len, nt_username_len,
|
||||
dir_drive_len, unknown_str_len, munged_dial_len,
|
||||
fullname_len, homedir_len, logon_script_len,
|
||||
profile_path_len, acct_desc_len, workstations_len;
|
||||
|
||||
uint32_t len = 0;
|
||||
uint32_t lm_pw_len, nt_pw_len, nt_pw_hist_len, hourslen;
|
||||
|
||||
if(sampass == NULL || buf.dptr == NULL) {
|
||||
DEBUG(0, ("init_sam_from_buffer_v2: NULL parameters found!\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
/* unpack the buffer into variables */
|
||||
len = tdb_unpack (tdb, (char *)buf.dptr, buf.dsize, TDB_FORMAT_STRING_V2,
|
||||
&sampass->logon_time, /* d */
|
||||
&sampass->logoff_time, /* d */
|
||||
&sampass->kickoff_time, /* d */
|
||||
&sampass->bad_password_time, /* d */
|
||||
&sampass->pass_last_set_time, /* d */
|
||||
&sampass->pass_can_change_time, /* d */
|
||||
&sampass->pass_must_change_time, /* d */
|
||||
&username_len, &sampass->username, /* B */
|
||||
&domain_len, &sampass->domain, /* B */
|
||||
&nt_username_len, &sampass->nt_username, /* B */
|
||||
&fullname_len, &sampass->fullname, /* B */
|
||||
&homedir_len, &sampass->homedir, /* B */
|
||||
&dir_drive_len, &sampass->dir_drive, /* B */
|
||||
&logon_script_len, &sampass->logon_script, /* B */
|
||||
&profile_path_len, &sampass->profile_path, /* B */
|
||||
&acct_desc_len, &sampass->acct_desc, /* B */
|
||||
&workstations_len, &sampass->workstations, /* B */
|
||||
&unknown_str_len, &sampass->unknown_str, /* B */
|
||||
&munged_dial_len, &sampass->munged_dial, /* B */
|
||||
&sampass->user_rid, /* d */
|
||||
&sampass->group_rid, /* d */
|
||||
&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 */
|
||||
/* Also "remove_me" field was removed. */
|
||||
&sampass->logon_divs, /* w */
|
||||
&sampass->hours_len, /* d */
|
||||
&hourslen, &sampass->hours, /* B */
|
||||
&sampass->bad_password_count, /* w */
|
||||
&sampass->logon_count, /* w */
|
||||
&sampass->unknown_6); /* d */
|
||||
|
||||
if (len == (uint32_t) -1) {
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
NTSTATUS samba3_read_tdbsam(const char *filename, TALLOC_CTX *ctx, struct samba3_samaccount **accounts, uint32_t *count)
|
||||
{
|
||||
int32_t version;
|
||||
TDB_CONTEXT *tdb;
|
||||
TDB_DATA key, val;
|
||||
|
||||
/* Try to open tdb passwd */
|
||||
if (!(tdb = tdb_open(filename, 0, TDB_DEFAULT, O_RDONLY, 0600))) {
|
||||
DEBUG(0, ("Unable to open TDB passwd file '%s'\n", filename));
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
/* Check the version */
|
||||
version = tdb_fetch_int32(tdb,
|
||||
TDBSAM_VERSION_STRING);
|
||||
if (version == -1)
|
||||
version = 0; /* Version not found, assume version 0 */
|
||||
|
||||
/* Compare the version */
|
||||
if (version > 2) {
|
||||
/* Version more recent than the latest known */
|
||||
DEBUG(0, ("TDBSAM version unknown: %d\n", version));
|
||||
tdb_close(tdb);
|
||||
return NT_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
*accounts = NULL;
|
||||
*count = 0;
|
||||
|
||||
for (key = tdb_firstkey(tdb); key.dptr; key = tdb_nextkey(tdb, key))
|
||||
{
|
||||
BOOL ret;
|
||||
if (strncmp((const char *)key.dptr, "USER_", 5) != 0)
|
||||
continue;
|
||||
|
||||
val = tdb_fetch(tdb, key);
|
||||
|
||||
*accounts = talloc_realloc(ctx, *accounts, struct samba3_samaccount, (*count)+1);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0: ret = init_sam_from_buffer_v0(tdb, &(*accounts)[*count], val); break;
|
||||
case 1: ret = init_sam_from_buffer_v1(tdb, &(*accounts)[*count], val); break;
|
||||
case 2: ret = init_sam_from_buffer_v2(tdb, &(*accounts)[*count], val); break;
|
||||
default: ret = False; break;
|
||||
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
DEBUG(0, ("Unable to parse SAM account %s\n", key.dptr));
|
||||
}
|
||||
|
||||
(*count)++;
|
||||
}
|
||||
|
||||
tdb_close(tdb);
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
Wins Database
|
||||
|
||||
Copyright (C) Jeremy Allison 1994-2003
|
||||
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
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "system/filesys.h"
|
||||
#include "lib/samba3/samba3.h"
|
||||
|
||||
#define WINS_VERSION 1
|
||||
|
||||
NTSTATUS samba3_read_winsdb( const char *fn, TALLOC_CTX *ctx, struct samba3_winsdb_entry **entries, uint32_t *count )
|
||||
{
|
||||
XFILE *fp;
|
||||
char *line;
|
||||
|
||||
if((fp = x_fopen(fn,O_RDONLY,0)) == NULL) {
|
||||
DEBUG(0,("initialise_wins: Can't open wins database file %s. Error was %s\n",
|
||||
fn, strerror(errno) ));
|
||||
return NT_STATUS_OPEN_FAILED;
|
||||
}
|
||||
|
||||
*count = 0;
|
||||
*entries = NULL;
|
||||
|
||||
while (!x_feof(fp)) {
|
||||
struct samba3_winsdb_entry entry;
|
||||
const char *name_str, *ttl_str, *nb_flags_str;
|
||||
const char **args;
|
||||
char *p;
|
||||
int i;
|
||||
unsigned int hash;
|
||||
int version;
|
||||
|
||||
/* Read a line from the wins.dat file. Strips whitespace
|
||||
from the beginning and end of the line. */
|
||||
line = fgets_slash(NULL,8,fp);
|
||||
if (!line) {
|
||||
return NT_STATUS_UNEXPECTED_IO_ERROR;
|
||||
}
|
||||
|
||||
if (*line == '#') {
|
||||
SAFE_FREE(line);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strncmp(line,"VERSION ", 8) == 0) {
|
||||
if (sscanf(line,"VERSION %d %u", &version, &hash) != 2 ||
|
||||
version != WINS_VERSION) {
|
||||
DEBUG(0,("Discarding invalid wins.dat file [%s]\n",line));
|
||||
SAFE_FREE(line);
|
||||
x_fclose(fp);
|
||||
return NT_STATUS_REVISION_MISMATCH;
|
||||
}
|
||||
SAFE_FREE(line);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
args = str_list_make_shell(ctx, line, NULL);
|
||||
|
||||
/*
|
||||
* Now we handle multiple IP addresses per name we need
|
||||
* to iterate over the line twice. The first time to
|
||||
* determine how many IP addresses there are, the second
|
||||
* time to actually parse them into the ip_list array.
|
||||
*/
|
||||
|
||||
name_str = args[0];
|
||||
if (!name_str) {
|
||||
DEBUG(0,("initialise_wins: Failed to parse name when parsing line %s\n", line ));
|
||||
SAFE_FREE(line);
|
||||
continue;
|
||||
}
|
||||
|
||||
ttl_str = args[1];
|
||||
if (!ttl_str) {
|
||||
DEBUG(0,("initialise_wins: Failed to parse time to live when parsing line %s\n", line ));
|
||||
SAFE_FREE(line);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine the number of IP addresses per line.
|
||||
*/
|
||||
entry.ip_count = 0;
|
||||
for (i = 2; args[i] && strchr(args[i], '.'); i++) entry.ip_count++;
|
||||
|
||||
if(entry.ip_count == 0) {
|
||||
DEBUG(0,("initialise_wins: Missing IP address when parsing line %s\n", line ));
|
||||
SAFE_FREE(line);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Allocate the space for the ip_list. */
|
||||
if((entry.ips = talloc_array ( ctx, struct ipv4_addr, entry.ip_count)) == NULL) {
|
||||
DEBUG(0,("initialise_wins: Malloc fail !\n"));
|
||||
SAFE_FREE(line);
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
/* Reset and re-parse the line. */
|
||||
for(i = 0; i < entry.ip_count; i++) {
|
||||
entry.ips[i] = interpret_addr2(args[i+2]);
|
||||
}
|
||||
nb_flags_str = args[2 + entry.ip_count];
|
||||
|
||||
SMB_ASSERT(nb_flags_str);
|
||||
|
||||
/*
|
||||
* Deal with SELF or REGISTER name encoding. Default is REGISTER
|
||||
* for compatibility with old nmbds.
|
||||
*/
|
||||
|
||||
if(nb_flags_str[strlen(nb_flags_str)-1] == 'S') {
|
||||
DEBUG(5,("initialise_wins: Ignoring SELF name %s\n", line));
|
||||
talloc_free(entry.ips);
|
||||
SAFE_FREE(line);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Netbios name. # divides the name from the type (hex): netbios#xx */
|
||||
entry.name = talloc_strdup(ctx, name_str);
|
||||
|
||||
if((p = strchr(entry.name,'#')) != NULL) {
|
||||
*p = 0;
|
||||
sscanf(p+1,"%x",&entry.type);
|
||||
}
|
||||
|
||||
/* Decode the netbios flags (hex) and the time-to-live (in seconds). */
|
||||
sscanf(nb_flags_str,"%x",&entry.nb_flags);
|
||||
entry.ttl = atol(ttl_str);
|
||||
|
||||
*entries = talloc_realloc(ctx, *entries, struct samba3_winsdb_entry, (*count)+1);
|
||||
(*entries)[*count] = entry;
|
||||
|
||||
(*count)++;
|
||||
}
|
||||
|
||||
x_fclose(fp);
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
Reference in New Issue
Block a user