From 85a12fe9af036577064bee17fee9f4987e6a62ed Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 20 Aug 2005 23:28:14 +0000 Subject: r9437: Update PLAN and README for Samba3 compatibility layer Add support for reading tdbsam files (This used to be commit 75ac972909ac601fb876e208a992eeebafaf6417) --- source4/lib/samba3/PLAN | 34 ++++-- source4/lib/samba3/README | 2 +- source4/lib/samba3/config.mk | 10 ++ source4/lib/samba3/sam.h | 52 +++++++++ source4/lib/samba3/tdbsam.c | 266 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 354 insertions(+), 10 deletions(-) create mode 100644 source4/lib/samba3/config.mk create mode 100644 source4/lib/samba3/sam.h create mode 100644 source4/lib/samba3/tdbsam.c (limited to 'source4/lib') diff --git a/source4/lib/samba3/PLAN b/source4/lib/samba3/PLAN index a75c60018c..6e83e8fc33 100644 --- a/source4/lib/samba3/PLAN +++ b/source4/lib/samba3/PLAN @@ -1,9 +1,25 @@ -- Each of the various password database backends(tdb,ldap,smbpaswd) available in Samba3 need to be accessible and converted to the SAM database in Samba4. -- Printer database needs to be read from the Samba3 TDB and added to the apprioprate LDAP subtree. -- The WINS database needs to be converted from both plain text file and TDB file to LDAP/LDB. -- The account policy database needs to be read in from a TDB and applied to the data in LDAP/LDB. -- The privilege database needs to be read from a TDB and added to the SAM database in LDB. -- Group mappings need to be read from the TDB and added to the SAM database. -- The share info database and the configuration file from Samba3 need to be read and converted to either xattrs or a TDB in Samba4 -- Secrets.tdb, containing the domain formation, needs to be merged into the SAM database. -- Last, but not least, a Samba3 configuration file should be parsable in Samba4. This file can be used for producing a Samba4 smb.conf file as well as for updating the various databases mentioned above. +Three possible viable approaches: + 1) TDB conversion approach. Read in TDB dump out LDIF (one-way) + - samr.ldb: from tdbsam/smbpasswd, account_policy.tdb, secrets.tdb, group_mapping.tdb, idmap.tdb, privilege.tdb + - registry.ldb: from registry.tdb + - wins.ldif: from wins.tdb/wins.dat + - smb.conf/ea's: generated from the old smb.conf + share_info.tdb + + (one-way upgrades can be done by using ldbsearch -a on these dynamically + generated ldb's) + + 2) samr "mapping" backend (alternative for samr.ldb) (two-way) + + 3) The vampire way of doing things (one-way) + - samba3 pidl backend + - Samba4 vampire + server side samsync support in Samba3 + - unixinfo (\unixinfo) + - in Samba4 (client side) + - in Samba3 (server side) + - winsrepl (thru seperate pipe?) + - enum/add shares (\srvsvc) + - enum/add registry (\winreg) + - enum/add printers (\winreg, perhaps also \spoolss(?)) + - convert smb.conf (using Jerry's registry hack) + +(going with a combination of 1 and 2) diff --git a/source4/lib/samba3/README b/source4/lib/samba3/README index cf55be047a..3f6553f7e8 100644 --- a/source4/lib/samba3/README +++ b/source4/lib/samba3/README @@ -1,5 +1,5 @@ This directory contains various files and functions for the purpose of -Samba3 import, migration and compatability. +Samba3 import, migration and compatibility. For example, the first file in this directory (smbpasswd.c) handles portions of the smbpasswd file format. diff --git a/source4/lib/samba3/config.mk b/source4/lib/samba3/config.mk new file mode 100644 index 0000000000..43608577c5 --- /dev/null +++ b/source4/lib/samba3/config.mk @@ -0,0 +1,10 @@ +################################################ +# Start SUBSYSTEM LIBSAMBA3 +[SUBSYSTEM::LIBSAMBA3] +INIT_OBJ_FILES = \ + lib/samba3/smbpasswd.o \ + lib/samba3/tdbsam.o +# End SUBSYSTEM LIBSAMBA3 +################################################ + + diff --git a/source4/lib/samba3/sam.h b/source4/lib/samba3/sam.h new file mode 100644 index 0000000000..11a9f42ec7 --- /dev/null +++ b/source4/lib/samba3/sam.h @@ -0,0 +1,52 @@ +/* + Unix SMB/CIFS implementation. + Registry interface + 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_SAM_H /* _SAMBA3_SAM_H */ +#define _SAMBA3_SAM_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; + uint8_t *lm_pw_ptr, *nt_pw_ptr; + uint8_t *nt_pw_hist_ptr; + uint8_t *hours; +}; + +#endif /* _SAMBA3_SAM_H */ diff --git a/source4/lib/samba3/tdbsam.c b/source4/lib/samba3/tdbsam.c new file mode 100644 index 0000000000..0b2f975441 --- /dev/null +++ b/source4/lib/samba3/tdbsam.c @@ -0,0 +1,266 @@ +/* + Unix SMB/CIFS implementation. + tdb passdb backend format routines + + Copyright (C) Andrew Tridgell 1992-1998 + Copyright (C) Simo Sorce 2000-2003 + Copyright (C) Gerald Carter 2000 + Copyright (C) Jeremy Allison 2001 + Copyright (C) Andrew Bartlett 2002 + 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/iconv.h" +#include "lib/tdb/include/tdbutil.h" +#include "lib/samba3/sam.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" + +/** + * Open the TDB passwd database, check version and convert it if needed. + * @param name filename of the tdbsam file. + * @param open_flags file access mode. + * @return a TDB_CONTEXT handle on the tdbsam file. + **/ + +static TDB_CONTEXT * tdbsam_open (const char *name, int open_flags, int32_t *version) +{ + TDB_CONTEXT *pdb_tdb; + + /* Try to open tdb passwd */ + if (!(pdb_tdb = tdb_open(name, 0, TDB_DEFAULT, + open_flags, 0600))) { + DEBUG(0, ("Unable to open/create TDB passwd\n")); + return NULL; + } + + /* Check the version */ + *version = tdb_fetch_int32(pdb_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(pdb_tdb); + pdb_tdb = NULL; + } + + return pdb_tdb; +} + +static BOOL init_sam_from_buffer_v0(TDB_CONTEXT *tdb, struct samba3_samaccount *sampass, uint8_t *buf, uint32_t buflen) +{ + 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 == 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, buflen, 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_ptr, /* B */ + &nt_pw_len, &sampass->nt_pw_ptr, /* 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; + } + + if (lm_pw_len != 16) { + sampass->lm_pw_ptr = NULL; + } + + if (nt_pw_len != 16) { + sampass->nt_pw_ptr = NULL; + } + + return True; +} + +static BOOL init_sam_from_buffer_v1(TDB_CONTEXT *tdb, struct samba3_samaccount *sampass, uint8_t *buf, uint32_t buflen) +{ + 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 == 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, buflen, 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_ptr, /* B */ + &nt_pw_len, &sampass->nt_pw_ptr, /* 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; + } + + if (sampass->lm_pw_ptr && lm_pw_len != 16) { + sampass->lm_pw_ptr = NULL; + } + + if (sampass->nt_pw_ptr && nt_pw_len != 16) { + sampass->nt_pw_ptr = NULL; + } + + return True; +} + +static BOOL init_sam_from_buffer_v2(TDB_CONTEXT *tdb, struct samba3_samaccount *sampass, uint8_t *buf, uint32_t buflen) +{ + 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 == 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, buflen, 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_ptr, /* B */ + &nt_pw_len, &sampass->nt_pw_ptr, /* 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; + } + + if (sampass->lm_pw_ptr && lm_pw_len != 16) { + sampass->lm_pw_ptr = NULL; + } + + if (sampass->nt_pw_ptr && nt_pw_len != 16) { + sampass->nt_pw_ptr = NULL; + } + + return True; +} -- cgit