wmi-1.3.16 from opsview.com

This commit is contained in:
Are Casilla
2019-02-16 00:16:52 +01:00
parent 163fdd3d1b
commit 17b3af2911
2146 changed files with 678824 additions and 0 deletions
+8
View File
@@ -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.
+68
View File
@@ -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)
+15
View File
@@ -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
################################################
+142
View File
@@ -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;
}
+99
View File
@@ -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;
}
+51
View File
@@ -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;
}
+148
View File
@@ -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;
}
+133
View File
@@ -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;
}
+215
View File
@@ -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 */
+264
View File
@@ -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;
}
+90
View File
@@ -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;
}
+347
View File
@@ -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;
}
+264
View File
@@ -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;
}
+160
View File
@@ -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;
}