mirror of
https://github.com/samba-team/samba.git
synced 2024-12-24 21:34:56 +03:00
Benjamin Kuit's MYSQL SAM Database implementation.
Copyright (C) Benjamin Kuit <bj@mcs.uts.edu.au> 1999.
This commit is contained in:
parent
8b859797aa
commit
fdf61e1dab
@ -160,11 +160,11 @@ GROUPDB_OBJ = groupdb/groupdb.o groupdb/aliasdb.o groupdb/builtindb.o \
|
||||
passdb/passgrp.o passdb/smbpassgroup.o \
|
||||
passdb/smbpassgroupunix.o passdb/passgrpldap.o
|
||||
|
||||
SAMPASSDB_OBJ = passdb/sampassdb.o passdb/sampass.o passdb/sampassldap.o
|
||||
SAMPASSDB_OBJ = passdb/sampassdb.o passdb/sampass.o passdb/sampassldap.o passdb/mysqlsampass.o
|
||||
|
||||
PASSDB_OBJ = passdb/passdb.o passdb/smbpassfile.o passdb/smbpass.o \
|
||||
passdb/pass_check.o passdb/ldap.o passdb/nispass.o \
|
||||
passdb/smbpasschange.o \
|
||||
passdb/smbpasschange.o passdb/mysqlpass.o \
|
||||
lib/util_pwdb.o lib/domain_namemap.o lib/sids.o
|
||||
|
||||
SMBD_OBJ1 = smbd/server.o smbd/files.o smbd/chgpasswd.o smbd/connection.o \
|
||||
|
@ -679,6 +679,8 @@ prots[] =
|
||||
{PROTOCOL_LANMAN2,"Samba"},
|
||||
{PROTOCOL_NT1,"NT LANMAN 1.0"},
|
||||
{PROTOCOL_NT1,"NT LM 0.12"},
|
||||
#if 0
|
||||
#endif
|
||||
{-1,NULL}
|
||||
};
|
||||
|
||||
|
@ -231,6 +231,13 @@ typedef struct
|
||||
BOOL bNTPipeSupport;
|
||||
BOOL bStatCache;
|
||||
BOOL bKernelOplocks;
|
||||
#if defined(WITH_MYSQL) || defined(WITH_MYSQLSAM)
|
||||
char *sMysqlDatabase;
|
||||
char *sMysqlTable;
|
||||
char *sMysqlUser;
|
||||
char *sMysqlHost;
|
||||
char *sMysqlPassFile;
|
||||
#endif
|
||||
} global;
|
||||
|
||||
static global Globals;
|
||||
@ -747,6 +754,14 @@ static struct parm_struct parm_table[] =
|
||||
{"ldap passwd file", P_STRING, P_GLOBAL, &Globals.szLdapPasswdFile, NULL, NULL, 0},
|
||||
#endif /* WITH_LDAP */
|
||||
|
||||
#if defined(WITH_MYSQL) || defined(WITH_MYSQLSAM)
|
||||
{"MySQL Options", P_SEP, P_SEPARATOR},
|
||||
{"mysql host", P_STRING, P_GLOBAL, &Globals.sMysqlHost, NULL, NULL, 0},
|
||||
{"mysql user", P_STRING, P_GLOBAL, &Globals.sMysqlUser, NULL, NULL, 0},
|
||||
{"mysql pass file", P_STRING, P_GLOBAL, &Globals.sMysqlPassFile, NULL, NULL, 0},
|
||||
{"mysql database", P_STRING, P_GLOBAL, &Globals.sMysqlDatabase, NULL, NULL, 0},
|
||||
{"mysql table", P_STRING, P_GLOBAL, &Globals.sMysqlTable, NULL, NULL, 0},
|
||||
#endif /* WITH_MYSQL */
|
||||
|
||||
{"Miscellaneous Options", P_SEP, P_SEPARATOR},
|
||||
|
||||
@ -971,6 +986,14 @@ static void init_globals(void)
|
||||
*/
|
||||
Globals.bKernelOplocks = True;
|
||||
|
||||
#if defined(WITH_MYSQL) || defined(WITH_MYSQLSAM)
|
||||
string_set(&Globals.sMysqlHost,"localhost");
|
||||
string_set(&Globals.sMysqlUser,"root");
|
||||
string_set(&Globals.sMysqlPassFile,NULL);
|
||||
string_set(&Globals.sMysqlDatabase,"samba");
|
||||
string_set(&Globals.sMysqlTable,"smbpasswd");
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This must be done last as it checks the value in
|
||||
* client_code_page.
|
||||
@ -1329,6 +1352,13 @@ FN_LOCAL_INTEGER(lp_printing,iPrinting)
|
||||
|
||||
FN_LOCAL_CHAR(lp_magicchar,magic_char)
|
||||
|
||||
#if defined(WITH_MYSQL) || defined(WITH_MYSQLSAM)
|
||||
FN_GLOBAL_STRING(lp_mysql_host,&Globals.sMysqlHost)
|
||||
FN_GLOBAL_STRING(lp_mysql_user,&Globals.sMysqlUser)
|
||||
FN_GLOBAL_STRING(lp_mysql_passfile,&Globals.sMysqlPassFile)
|
||||
FN_GLOBAL_STRING(lp_mysql_db,&Globals.sMysqlDatabase)
|
||||
FN_GLOBAL_STRING(lp_mysql_table,&Globals.sMysqlTable)
|
||||
#endif
|
||||
|
||||
|
||||
/* local prototypes */
|
||||
|
668
source/passdb/mysqlpass.c
Normal file
668
source/passdb/mysqlpass.c
Normal file
@ -0,0 +1,668 @@
|
||||
/*
|
||||
* Unix SMB/Netbios implementation.
|
||||
* Version 1.9.
|
||||
* Samba MYSQL SAM Database, by Benjamin Kuit.
|
||||
* Copyright (C) Benjamin Kuit 1999,
|
||||
* Copyright (C) Andrew Tridgell 1992-1999,
|
||||
* Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if defined(WITH_MYSQL) || defined(WITH_MYSQLSAM)
|
||||
|
||||
#include "includes.h"
|
||||
#include <mysql.h>
|
||||
|
||||
extern int DEBUGLEVEL;
|
||||
|
||||
#define UNIX_NAME(row) ((*row)[0])
|
||||
#define UNIX_UID(row) ((*row)[1])
|
||||
#define NT_NAME(row) ((*row)[2])
|
||||
#define RID(row) ((*row)[3])
|
||||
#define LM_HASH(row) ((*row)[4])
|
||||
#define NT_HASH(row) ((*row)[5])
|
||||
#define FLAGS(row) ((*row)[6])
|
||||
#define CHANGE_TIME(row) ((*row)[7])
|
||||
|
||||
void *mysql_fill_smb_passwd( MYSQL_ROW *row );
|
||||
|
||||
typedef void *(*mysql_fill_func)( MYSQL_ROW * );
|
||||
#define FILL_SMB mysql_fill_smb_passwd
|
||||
|
||||
void *mysql_startpwent(BOOL update);
|
||||
void mysql_endpwent(void *vp);
|
||||
SMB_BIG_UINT mysql_getpwpos(void *vp);
|
||||
BOOL mysql_setpwpos(void *vp, SMB_BIG_UINT pos);
|
||||
void *mysql_fill_smb_passwd( MYSQL_ROW *row );
|
||||
MYSQL_ROW *mysql_getpwent(void *vp);
|
||||
void *mysql_fetch_passwd( mysql_fill_func filler, char *where );
|
||||
void *mysql_getpwuid( mysql_fill_func filler, uid_t uid );
|
||||
void *mysql_getpwnam( mysql_fill_func filler, char *field, const char *name );
|
||||
int mysql_db_lock_connect( MYSQL *handle );
|
||||
BOOL mysql_add_smb( MYSQL *handle, struct smb_passwd *smb );
|
||||
BOOL mysql_mod_smb( MYSQL *handle, struct smb_passwd *smb, BOOL override );
|
||||
BOOL mysql_del_smb( MYSQL *handle, char *unix_name );
|
||||
|
||||
static fstring mysql_table = { 0 };
|
||||
|
||||
struct mysql_struct {
|
||||
MYSQL handle;
|
||||
MYSQL_RES *result;
|
||||
uint current_row;
|
||||
};
|
||||
typedef struct mysql_struct mysql_ctrl;
|
||||
|
||||
static char *mysql_retrieve_password(char *passfile) {
|
||||
static fstring pass;
|
||||
static time_t last_checked = (time_t)0;
|
||||
static char pass_chars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()_-+=|~`\\{}[]:;\"'?/>.<,";
|
||||
fstring temppass;
|
||||
FILE *filep;
|
||||
int length;
|
||||
|
||||
DEBUG(5,("%s\n",FUNCTION_MACRO));
|
||||
|
||||
if ( passfile == NULL ) {
|
||||
pass[0]=0;
|
||||
return pass;
|
||||
}
|
||||
|
||||
if ( time(NULL) - last_checked <= 60 ) {
|
||||
return pass;
|
||||
}
|
||||
|
||||
if ( file_modtime(passfile) < last_checked ) {
|
||||
return pass;
|
||||
}
|
||||
|
||||
filep = sys_fopen(passfile,"r");
|
||||
|
||||
if ( filep == NULL ) {
|
||||
return pass;
|
||||
}
|
||||
|
||||
memset(temppass,0,sizeof(temppass));
|
||||
|
||||
if ( fgets( temppass, sizeof(temppass)-1, filep) == NULL ) {
|
||||
fclose(filep);
|
||||
return pass;
|
||||
}
|
||||
|
||||
fclose(filep);
|
||||
|
||||
length = strspn( temppass, pass_chars );
|
||||
temppass[length<sizeof(temppass)-1?length:sizeof(temppass)-1] = '\0';
|
||||
|
||||
fstrcpy( pass, temppass );
|
||||
|
||||
last_checked = time(NULL);
|
||||
|
||||
return pass;
|
||||
}
|
||||
|
||||
static int mysql_db_connect( MYSQL *handle ) {
|
||||
char *password;
|
||||
|
||||
DEBUG(5,("%s\n",FUNCTION_MACRO));
|
||||
|
||||
password = mysql_retrieve_password(lp_mysql_passfile());
|
||||
|
||||
if ( !mysql_connect(handle, lp_mysql_host(), lp_mysql_user(), password) ) {
|
||||
DEBUG(0,("mysql_connect: %s\n",mysql_error(handle)));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( mysql_select_db( handle, lp_mysql_db()) ) {
|
||||
DEBUG(0,("mysql_connect: %s\n",mysql_error(handle)));
|
||||
mysql_close(handle);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fstrcpy(mysql_table,lp_mysql_table());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mysql_lock_table( MYSQL *handle, BOOL write_access ) {
|
||||
fstring query;
|
||||
|
||||
DEBUG(5,("%s\n",FUNCTION_MACRO));
|
||||
|
||||
slprintf( query, sizeof(query), "lock tables %s %s", mysql_table, write_access==True?"write":"read");
|
||||
|
||||
if ( mysql_query( handle, query ) ) {
|
||||
DEBUG(0,("Cannot get lock: %s: %s\n",query,mysql_error(handle) ));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mysql_db_lock_connect( MYSQL *handle ) {
|
||||
|
||||
DEBUG(5,("%s\n",FUNCTION_MACRO));
|
||||
|
||||
if ( mysql_db_connect( handle ) ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( mysql_lock_table( handle, True ) ) {
|
||||
mysql_close( handle );
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static MYSQL_RES *mysql_select_results( MYSQL *handle, char *selection ) {
|
||||
MYSQL_RES *result;
|
||||
pstring query;
|
||||
int query_length;
|
||||
char select[] = "select ";
|
||||
char where[] = " where ";
|
||||
char from[] = " from ";
|
||||
char mysql_query_string[] = "unix_name, unix_uid, nt_name, user_rid, smb_passwd, smb_nt_passwd, acct_ctrl, pass_last_set_time";
|
||||
|
||||
DEBUG(5,("%s\n",FUNCTION_MACRO));
|
||||
|
||||
query_length = sizeof( select ) + sizeof( mysql_query_string ) + sizeof(from ) + strlen( mysql_table );
|
||||
|
||||
if ( selection != NULL && *selection != '\0' ) {
|
||||
query_length += sizeof( where ) + strlen( selection );
|
||||
}
|
||||
|
||||
if ( query_length >= sizeof( query ) ) {
|
||||
DEBUG(0,("Query string too long\n"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pstrcpy( query, select);
|
||||
pstrcat( query, mysql_query_string );
|
||||
pstrcat( query, from );
|
||||
pstrcat( query, mysql_table );
|
||||
|
||||
if ( selection != NULL && *selection != '\0' ) {
|
||||
pstrcat( query, where );
|
||||
pstrcat( query, selection );
|
||||
}
|
||||
|
||||
DEBUG(5,("mysql> %s\n",query));
|
||||
if ( mysql_query( handle, query ) ) {
|
||||
DEBUG(0,("%s: %s\n", query, mysql_error(handle) ));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result = mysql_store_result( handle );
|
||||
|
||||
if ( mysql_num_fields( result ) != 8 ) {
|
||||
DEBUG(0,("mysql_num_result = %d (!=8)\n",mysql_num_fields( result )));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( result == NULL ) {
|
||||
DEBUG(0,("mysql_store_result: %s\n",mysql_error(handle)));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void *mysql_startpwent( BOOL update ) {
|
||||
mysql_ctrl *mysql;
|
||||
|
||||
DEBUG(5,("%s\n",FUNCTION_MACRO));
|
||||
|
||||
mysql = (mysql_ctrl *)malloc( sizeof(mysql_ctrl) );
|
||||
if ( mysql == NULL ) {
|
||||
DEBUG(0,("malloc: Out of memory\n"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset( mysql, 0, sizeof(mysql_ctrl) );
|
||||
|
||||
if ( mysql_db_connect( &mysql->handle ) ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( mysql_lock_table( &mysql->handle, update ) ) {
|
||||
mysql_close( &mysql->handle );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mysql->result = mysql_select_results( &mysql->handle, NULL );
|
||||
|
||||
if ( mysql->result == NULL ) {
|
||||
mysql_close( &mysql->handle );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mysql->current_row = 0;
|
||||
|
||||
return (void*)mysql;
|
||||
}
|
||||
|
||||
void mysql_endpwent( void *ptr ) {
|
||||
mysql_ctrl *handle;
|
||||
|
||||
DEBUG(5,("%s\n",FUNCTION_MACRO));
|
||||
handle = (mysql_ctrl *)ptr;
|
||||
|
||||
mysql_free_result( handle->result );
|
||||
|
||||
mysql_close( &handle->handle );
|
||||
|
||||
free( handle );
|
||||
}
|
||||
|
||||
SMB_BIG_UINT mysql_getpwpos(void *vp) {
|
||||
|
||||
DEBUG(5,("%s\n",FUNCTION_MACRO));
|
||||
|
||||
return ((mysql_ctrl *)vp)->current_row;
|
||||
}
|
||||
|
||||
BOOL mysql_setpwpos(void *vp, SMB_BIG_UINT pos) {
|
||||
|
||||
DEBUG(5,("%s\n",FUNCTION_MACRO));
|
||||
|
||||
mysql_data_seek( ((mysql_ctrl*)vp)->result, (uint)pos );
|
||||
((mysql_ctrl *)vp)->current_row=(uint)pos;
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
static void quote_hash( char *target, unsigned char *passwd ) {
|
||||
char hex[] = "0123456789ABCDEF";
|
||||
int i;
|
||||
|
||||
DEBUG(5,("%s\n",FUNCTION_MACRO));
|
||||
|
||||
if ( passwd == NULL ) {
|
||||
fstrcpy(target,"NULL");
|
||||
}
|
||||
else {
|
||||
target[0]='\'';
|
||||
for (i=0;i<32;i++) {
|
||||
target[i+1] = hex[(passwd[i>>1]>>(((~i)&1)<<2))&15];
|
||||
}
|
||||
target[33] = '\'';
|
||||
target[34] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned char *decode_hash( char *hash, unsigned char *buffer ) {
|
||||
char hex[] = "0123456789ABCDEF";
|
||||
int pos, v1, v2;
|
||||
|
||||
DEBUG(5,("%s\n",FUNCTION_MACRO));
|
||||
|
||||
if ( hash == NULL ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (pos=0;pos<16;pos++) {
|
||||
for( v1 = 0; v1 < sizeof(hex) && hash[0] != hex[v1]; v1++ );
|
||||
for( v2 = 0; v2 < sizeof(hex) && hash[1] != hex[v2]; v2++ );
|
||||
|
||||
if ( v1 == sizeof(hex) || v2 == sizeof(hex) ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buffer[pos] = (v1<<4)|v2;
|
||||
hash += 2;
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void *mysql_fill_smb_passwd( MYSQL_ROW *row ) {
|
||||
static struct smb_passwd pw_buf;
|
||||
static fstring unix_name;
|
||||
static fstring nt_name;
|
||||
static unsigned char smbpwd[16];
|
||||
static unsigned char smbntpwd[16];
|
||||
|
||||
DEBUG(5,("%s\n",FUNCTION_MACRO));
|
||||
|
||||
pwdb_init_smb(&pw_buf);
|
||||
|
||||
fstrcpy( unix_name, UNIX_NAME(row) );
|
||||
pw_buf.unix_name = unix_name;
|
||||
pw_buf.unix_uid = get_number( UNIX_UID(row) );
|
||||
|
||||
if ( NT_NAME(row) != NULL ) {
|
||||
fstrcpy( nt_name, NT_NAME(row) );
|
||||
pw_buf.nt_name = nt_name;
|
||||
}
|
||||
|
||||
if ( RID(row) != NULL ) {
|
||||
pw_buf.user_rid = get_number( RID(row) );
|
||||
}
|
||||
|
||||
pw_buf.smb_passwd = decode_hash( LM_HASH(row), smbpwd );
|
||||
if ( !pw_buf.smb_passwd ) {
|
||||
DEBUG(4, ("entry invalidated for unix user %s\n", unix_name ));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pw_buf.smb_nt_passwd = decode_hash( NT_HASH(row), smbntpwd );
|
||||
|
||||
if ( FLAGS(row) != NULL ) {
|
||||
pw_buf.acct_ctrl = get_number( FLAGS(row) );
|
||||
}
|
||||
|
||||
if ( pw_buf.acct_ctrl == 0 ) {
|
||||
pw_buf.acct_ctrl = ACB_NORMAL;
|
||||
}
|
||||
|
||||
pw_buf.pass_last_set_time = get_number( CHANGE_TIME(row) );
|
||||
|
||||
return (void*)&pw_buf;
|
||||
}
|
||||
|
||||
MYSQL_ROW *mysql_getpwent(void *vp) {
|
||||
mysql_ctrl *mysql;
|
||||
static MYSQL_ROW row;
|
||||
|
||||
DEBUG(5,("%s\n",FUNCTION_MACRO));
|
||||
|
||||
mysql = (mysql_ctrl*)vp;
|
||||
row = mysql_fetch_row( mysql->result );
|
||||
|
||||
if ( row == NULL ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mysql->current_row++;
|
||||
|
||||
return &row;
|
||||
}
|
||||
|
||||
struct smb_passwd *mysql_getsmbpwent(void *vp) {
|
||||
|
||||
DEBUG(5,("%s\n",FUNCTION_MACRO));
|
||||
|
||||
return (struct smb_passwd*)mysql_fill_smb_passwd( mysql_getpwent(vp) );
|
||||
}
|
||||
|
||||
void *mysql_fetch_passwd( mysql_fill_func filler, char *where ) {
|
||||
void *retval;
|
||||
MYSQL handle;
|
||||
MYSQL_RES *result;
|
||||
MYSQL_ROW row;
|
||||
|
||||
DEBUG(5,("%s\n",FUNCTION_MACRO));
|
||||
|
||||
if ( filler == NULL ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( where == NULL || *where == '\0' ) {
|
||||
DEBUG(0,("Null or empty query\n"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( mysql_db_connect( &handle ) ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result = mysql_select_results( &handle, where );
|
||||
if ( result == NULL ) {
|
||||
mysql_close( &handle );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
row = mysql_fetch_row ( result );
|
||||
if ( row == NULL ) {
|
||||
mysql_free_result( result );
|
||||
mysql_close( &handle );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( DEBUGLEVEL >= 7 ) {
|
||||
int field;
|
||||
for (field=0; field< mysql_num_fields( result ); field++ ) {
|
||||
DEBUG(7,(" row[%d] = \"%s\"\n",field,row[field]?row[field]:"NULL"));
|
||||
}
|
||||
}
|
||||
|
||||
retval = (*filler)( &row );
|
||||
|
||||
mysql_free_result( result );
|
||||
mysql_close( &handle );
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
void *mysql_getpwuid(mysql_fill_func filler, uid_t uid) {
|
||||
fstring where;
|
||||
|
||||
DEBUG(5,("%s\n",FUNCTION_MACRO));
|
||||
|
||||
slprintf( where, sizeof(where), "unix_uid=%lu", uid);
|
||||
|
||||
return mysql_fetch_passwd(filler,where);
|
||||
}
|
||||
|
||||
struct smb_passwd *mysql_getsmbpwuid(uid_t uid) {
|
||||
|
||||
DEBUG(5,("%s\n",FUNCTION_MACRO));
|
||||
|
||||
return (struct smb_passwd *)mysql_getpwuid( FILL_SMB, uid );
|
||||
}
|
||||
|
||||
void *mysql_getpwnam(mysql_fill_func filler, char *field, const char *name) {
|
||||
fstring where;
|
||||
char format[] = "%s='%s'";
|
||||
|
||||
DEBUG(5,("%s\n",FUNCTION_MACRO));
|
||||
|
||||
if ( filler == NULL ) {
|
||||
DEBUG(0,("Empty fill opteration\n"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( field == NULL || *field == '\0' ) {
|
||||
DEBUG(0,("Empty or NULL field name\n"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( name == NULL || *name == '\0' ) {
|
||||
DEBUG(0,("Empty or NULL query\n"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( sizeof(format) + strlen(name) + strlen(field) > sizeof(where) ) {
|
||||
DEBUG(0,("Query string too long\n"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
slprintf(where, sizeof( where ), format, field, name );
|
||||
|
||||
return mysql_fetch_passwd( filler, where );
|
||||
}
|
||||
|
||||
struct smb_passwd *mysql_getsmbpwnam(const char *unix_name) {
|
||||
DEBUG(5,("%s\n",FUNCTION_MACRO));
|
||||
|
||||
return mysql_getpwnam( FILL_SMB, "unix_name", unix_name );
|
||||
}
|
||||
|
||||
static void quote_string(char *target, char *string) {
|
||||
DEBUG(5,("%s\n",FUNCTION_MACRO));
|
||||
|
||||
if ( string == NULL ) {
|
||||
fstrcpy( target, "NULL" );
|
||||
}
|
||||
else {
|
||||
target[0] = '\'';
|
||||
safe_strcpy(&target[1],string,sizeof(fstring)-2);
|
||||
safe_strcpy(&target[strlen(target)],"'",2);
|
||||
}
|
||||
}
|
||||
|
||||
BOOL mysql_del_smb( MYSQL *handle, char *unix_name ) {
|
||||
pstring query;
|
||||
char format[] = "delete from %s where unix_name='%s'";
|
||||
|
||||
DEBUG(5,("%s\n",FUNCTION_MACRO));
|
||||
|
||||
if (strlen( format ) + strlen(mysql_table) + strlen(unix_name)) {
|
||||
return False;
|
||||
}
|
||||
|
||||
slprintf( query, sizeof(query), format, mysql_table, unix_name);
|
||||
|
||||
if ( mysql_query( handle, query ) ) {
|
||||
DEBUG(0,("%s: %s\n", query, mysql_error(handle) ));
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
BOOL mysql_add_smb( MYSQL *handle, struct smb_passwd *smb ) {
|
||||
pstring query;
|
||||
char format[] = "insert into %s (unix_name, unix_uid) values ( '%s', %lu )";
|
||||
|
||||
DEBUG(5,("%s\n",FUNCTION_MACRO));
|
||||
|
||||
if ( strlen(format) + strlen(mysql_table) + strlen(smb->unix_name) + 10 > sizeof(query) ) {
|
||||
DEBUG(0,("Query too long\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
slprintf( query, sizeof(query), "insert into %s (unix_name,unix_uid) values ('%s', %lu)", mysql_table, smb->unix_name, smb->unix_uid);
|
||||
|
||||
if ( mysql_query( handle, query ) ) {
|
||||
DEBUG(0,("%s: %s\n",query,mysql_error(handle) ));
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
BOOL mysql_mod_smb( MYSQL *handle, struct smb_passwd *smb, BOOL override ) {
|
||||
pstring query;
|
||||
fstring smb_passwd;
|
||||
fstring smb_nt_passwd;
|
||||
fstring nt_name;
|
||||
|
||||
char format[] = "update %s set nt_name=%s, user_rid=%lu, smb_passwd=%s, smb_nt_passwd=%s, acct_ctrl=%u, pass_last_set_time=unix_timestamp() where unix_name='%s'";
|
||||
char extra[] = " and not ISNULL(smb_passwd)";
|
||||
|
||||
DEBUG(5,("%s\n",FUNCTION_MACRO));
|
||||
|
||||
if ( strlen(format) + 2*20 + 3*10 + 2*32 + strlen(mysql_table) >= sizeof( query ) + strlen( extra ) ) {
|
||||
DEBUG(0,("Query string too long\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
quote_hash(smb_passwd, smb->smb_passwd);
|
||||
quote_hash(smb_nt_passwd, smb->smb_nt_passwd);
|
||||
|
||||
quote_string(nt_name, smb->nt_name);
|
||||
|
||||
slprintf( query, sizeof(query), format, mysql_table, nt_name, (long unsigned)smb->user_rid, smb_passwd, smb_nt_passwd, smb->acct_ctrl, smb->unix_name);
|
||||
|
||||
if ( override != True ) {
|
||||
pstrcat( query, extra );
|
||||
}
|
||||
|
||||
if ( mysql_query( handle, query ) ) {
|
||||
DEBUG(0,("%s: %s\n",query,mysql_error(handle) ));
|
||||
return False;
|
||||
}
|
||||
|
||||
if ( mysql_affected_rows( handle ) < 1 ) {
|
||||
DEBUG(3,("No entries changed\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
BOOL mysql_add_smbpwd_entry(struct smb_passwd *smb) {
|
||||
MYSQL handle;
|
||||
|
||||
DEBUG(5,("%s\n",FUNCTION_MACRO));
|
||||
|
||||
if ( smb == NULL ) {
|
||||
return False;
|
||||
}
|
||||
|
||||
if ( mysql_db_lock_connect( &handle ) ) {
|
||||
return False;
|
||||
}
|
||||
|
||||
if ( !mysql_add_smb( &handle, smb ) ) {
|
||||
mysql_close( &handle );
|
||||
return False;
|
||||
}
|
||||
|
||||
if ( !mysql_mod_smb( &handle, smb, True ) ) {
|
||||
mysql_del_smb( &handle, smb->unix_name );
|
||||
mysql_close( &handle );
|
||||
return False;
|
||||
}
|
||||
|
||||
mysql_close(&handle);
|
||||
return True;
|
||||
}
|
||||
|
||||
BOOL mysql_mod_smbpwd_entry(struct smb_passwd *smb, BOOL override) {
|
||||
MYSQL handle;
|
||||
|
||||
DEBUG(5,("%s\n",FUNCTION_MACRO));
|
||||
|
||||
if ( smb == NULL ) {
|
||||
return False;
|
||||
}
|
||||
|
||||
if ( mysql_db_lock_connect( &handle ) ) {
|
||||
return False;
|
||||
}
|
||||
|
||||
if ( !mysql_mod_smb( &handle, smb, override ) ) {
|
||||
mysql_close(&handle);
|
||||
return False;
|
||||
}
|
||||
|
||||
mysql_close(&handle);
|
||||
return True;
|
||||
}
|
||||
|
||||
static struct smb_passdb_ops mysql_ops = {
|
||||
mysql_startpwent,
|
||||
mysql_endpwent,
|
||||
mysql_getpwpos,
|
||||
mysql_setpwpos,
|
||||
mysql_getsmbpwnam,
|
||||
mysql_getsmbpwuid,
|
||||
mysql_getsmbpwent,
|
||||
mysql_add_smbpwd_entry,
|
||||
mysql_mod_smbpwd_entry
|
||||
};
|
||||
|
||||
struct smb_passdb_ops *mysql_initialise_password_db(void)
|
||||
{
|
||||
(void*)mysql_retrieve_password(NULL);
|
||||
return &mysql_ops;
|
||||
}
|
||||
|
||||
#else
|
||||
void mysql_dummy_smb_function(void) { }
|
||||
#endif
|
265
source/passdb/mysqlsampass.c
Normal file
265
source/passdb/mysqlsampass.c
Normal file
@ -0,0 +1,265 @@
|
||||
/*
|
||||
* Unix SMB/Netbios implementation.
|
||||
* Version 1.9.
|
||||
* Samba MYSQL SAM Database, by Benjamin Kuit.
|
||||
* Copyright (C) Benjamin Kuit 1999,
|
||||
* Copyright (C) Andrew Tridgell 1992-1999,
|
||||
* Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef WITH_MYSQLSAM
|
||||
|
||||
#include "includes.h"
|
||||
#include <mysql.h>
|
||||
|
||||
extern int DEBUGLEVEL;
|
||||
|
||||
extern pstring samlogon_user;
|
||||
extern BOOL sam_logon_in_ssb;
|
||||
|
||||
typedef void *(*mysql_fill_func)( MYSQL_ROW * );
|
||||
#define FILL_SAM mysql_fill_sam_passwd
|
||||
|
||||
void *mysql_startpwent(BOOL update);
|
||||
void mysql_endpwent(void *vp);
|
||||
SMB_BIG_UINT mysql_getpwpos(void *vp);
|
||||
BOOL mysql_setpwpos(void *vp, SMB_BIG_UINT pos);
|
||||
void *mysql_fill_smb_passwd( MYSQL_ROW *row );
|
||||
MYSQL_ROW *mysql_getpwent(void *vp);
|
||||
void *mysql_fetch_passwd( mysql_fill_func filler, char *where );
|
||||
void *mysql_getpwuid( mysql_fill_func filler, uid_t uid );
|
||||
void *mysql_getpwnam( mysql_fill_func filler, char *field, const char *name );
|
||||
int mysql_db_lock_connect( MYSQL *handle );
|
||||
BOOL mysql_add_smb( MYSQL *handle, struct smb_passwd *smb );
|
||||
BOOL mysql_mod_smb( MYSQL *handle, struct smb_passwd *smb, BOOL override );
|
||||
BOOL mysql_del_smb( MYSQL *handle, char *unix_name );
|
||||
|
||||
void *mysql_fill_sam_passwd( MYSQL_ROW *row ) {
|
||||
static struct sam_passwd *user;
|
||||
|
||||
static pstring full_name;
|
||||
static pstring home_dir;
|
||||
static pstring home_drive;
|
||||
static pstring logon_script;
|
||||
static pstring profile_path;
|
||||
static pstring acct_desc;
|
||||
static pstring workstations;
|
||||
|
||||
DEBUG(5,("%s\n",FUNCTION_MACRO));
|
||||
|
||||
user = pwdb_smb_to_sam((struct smb_passwd *)mysql_fill_smb_passwd(row));
|
||||
|
||||
if ( user == NULL ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* 'Researched' from sampass.c =) */
|
||||
|
||||
pstrcpy(samlogon_user, user->unix_name);
|
||||
|
||||
if (samlogon_user[strlen(samlogon_user)-1] == '$' &&
|
||||
user->group_rid != DOMAIN_GROUP_RID_USERS)
|
||||
{
|
||||
DEBUG(0,("trust account %s should be in DOMAIN_GROUP_RID_USERS\n", samlogon_user));
|
||||
}
|
||||
|
||||
/* XXXX hack to get standard_sub_basic() to use sam logon username */
|
||||
/* possibly a better way would be to do a become_user() call */
|
||||
sam_logon_in_ssb = True;
|
||||
|
||||
pstrcpy(full_name , "");
|
||||
pstrcpy(logon_script , lp_logon_script ());
|
||||
pstrcpy(profile_path , lp_logon_path ());
|
||||
pstrcpy(home_drive , lp_logon_drive ());
|
||||
pstrcpy(home_dir , lp_logon_home ());
|
||||
pstrcpy(acct_desc , "");
|
||||
pstrcpy(workstations , "");
|
||||
|
||||
sam_logon_in_ssb = False;
|
||||
|
||||
user->full_name = full_name;
|
||||
user->home_dir = home_dir;
|
||||
user->dir_drive = home_drive;
|
||||
user->logon_script = logon_script;
|
||||
user->profile_path = profile_path;
|
||||
user->acct_desc = acct_desc;
|
||||
user->workstations = workstations;
|
||||
|
||||
user->unknown_str = NULL; /* don't know, yet! */
|
||||
user->munged_dial = NULL; /* "munged" dial-back telephone number */
|
||||
|
||||
user->unknown_3 = 0xffffff; /* don't know */
|
||||
user->logon_divs = 168; /* hours per week */
|
||||
user->hours_len = 21; /* 21 times 8 bits = 168 */
|
||||
memset(user->hours, 0xff, user->hours_len); /* available at all hours */
|
||||
user->unknown_5 = 0x00020000; /* don't know */
|
||||
user->unknown_6 = 0x000004ec; /* don't know */
|
||||
|
||||
return (void*)user;
|
||||
}
|
||||
|
||||
struct sam_passwd *mysql_getsampwent(void *vp) {
|
||||
|
||||
DEBUG(5,("%s\n",FUNCTION_MACRO));
|
||||
|
||||
return (struct sam_passwd*)mysql_fill_sam_passwd( mysql_getpwent(vp) );
|
||||
}
|
||||
|
||||
struct sam_passwd *mysql_getsampwrid(uint32 rid) {
|
||||
fstring where;
|
||||
|
||||
DEBUG(5,("%s\n",FUNCTION_MACRO));
|
||||
|
||||
slprintf( where, sizeof(where), "user_rid=%lu", (long unsigned)rid);
|
||||
|
||||
return (struct sam_passwd *)mysql_fetch_passwd( FILL_SAM, where );
|
||||
}
|
||||
|
||||
struct sam_passwd *mysql_getsampwuid(uid_t uid) {
|
||||
|
||||
DEBUG(5,("%s\n",FUNCTION_MACRO));
|
||||
|
||||
return (struct sam_passwd *)mysql_getpwuid( FILL_SAM, uid );
|
||||
}
|
||||
|
||||
struct sam_passwd *mysql_getsampwntnam(const char *nt_name) {
|
||||
|
||||
DEBUG(5,("%s\n",FUNCTION_MACRO));
|
||||
|
||||
return (struct sam_passwd *)mysql_getpwnam( FILL_SAM, "nt_name", nt_name);
|
||||
}
|
||||
|
||||
struct sam_disp_info *mysql_getsamdispntnam(const char *nt_name) {
|
||||
|
||||
DEBUG(5,("%s\n",FUNCTION_MACRO));
|
||||
|
||||
return pwdb_sam_to_dispinfo(mysql_getsampwntnam(nt_name));
|
||||
}
|
||||
|
||||
struct sam_disp_info *mysql_getsamdisprid(uint32 rid) {
|
||||
|
||||
DEBUG(5,("%s\n",FUNCTION_MACRO));
|
||||
|
||||
return pwdb_sam_to_dispinfo(mysql_getsampwrid(rid));
|
||||
}
|
||||
|
||||
struct sam_disp_info *mysql_getsamdispent(void *vp) {
|
||||
|
||||
DEBUG(5,("%s\n",FUNCTION_MACRO));
|
||||
|
||||
return pwdb_sam_to_dispinfo(mysql_getsampwent(vp));
|
||||
}
|
||||
|
||||
static BOOL mysql_mod_sam( MYSQL *handle, struct sam_passwd *sam, BOOL override ) {
|
||||
|
||||
DEBUG(5,("%s\n",FUNCTION_MACRO));
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
BOOL mysql_add_sampwd_entry(struct sam_passwd *sam) {
|
||||
MYSQL handle;
|
||||
struct smb_passwd *smb;
|
||||
|
||||
DEBUG(5,("%s\n",FUNCTION_MACRO));
|
||||
|
||||
smb = pwdb_sam_to_smb( sam );
|
||||
|
||||
if ( smb == NULL ) {
|
||||
return False;
|
||||
}
|
||||
|
||||
if ( mysql_db_lock_connect( &handle ) ) {
|
||||
return False;
|
||||
}
|
||||
|
||||
if ( !mysql_add_smb( &handle, smb ) ) {
|
||||
mysql_close(&handle);
|
||||
return False;
|
||||
}
|
||||
|
||||
if ( !mysql_mod_smb( &handle, smb, True ) ) {
|
||||
mysql_del_smb( &handle, smb->unix_name );
|
||||
mysql_close(&handle);
|
||||
return False;
|
||||
}
|
||||
|
||||
if ( !mysql_mod_sam( &handle, sam, True ) ) {
|
||||
mysql_del_smb( &handle, smb->unix_name );
|
||||
mysql_close(&handle);
|
||||
return False;
|
||||
}
|
||||
|
||||
mysql_close(&handle);
|
||||
return True;
|
||||
}
|
||||
|
||||
BOOL mysql_mod_sampwd_entry(struct sam_passwd *sam, BOOL override) {
|
||||
MYSQL handle;
|
||||
struct smb_passwd *smb;
|
||||
|
||||
DEBUG(5,("%s\n",FUNCTION_MACRO));
|
||||
|
||||
smb = pwdb_sam_to_smb(sam);
|
||||
|
||||
if ( smb == NULL ) {
|
||||
return False;
|
||||
}
|
||||
|
||||
if ( mysql_db_lock_connect( &handle ) ) {
|
||||
return False;
|
||||
}
|
||||
|
||||
if ( !mysql_mod_smb( &handle, smb, override ) ) {
|
||||
mysql_close(&handle);
|
||||
return False;
|
||||
}
|
||||
|
||||
if ( !mysql_mod_sam( &handle, sam, override ) ) {
|
||||
mysql_close(&handle);
|
||||
return False;
|
||||
}
|
||||
|
||||
mysql_close(&handle);
|
||||
return True;
|
||||
}
|
||||
|
||||
static struct sam_passdb_ops sam_mysql_ops =
|
||||
{
|
||||
mysql_startpwent,
|
||||
mysql_endpwent,
|
||||
mysql_getpwpos,
|
||||
mysql_setpwpos,
|
||||
mysql_getsampwntnam,
|
||||
mysql_getsampwuid,
|
||||
mysql_getsampwrid,
|
||||
mysql_getsampwent,
|
||||
mysql_add_sampwd_entry,
|
||||
mysql_mod_sampwd_entry,
|
||||
mysql_getsamdispntnam,
|
||||
mysql_getsamdisprid,
|
||||
mysql_getsamdispent
|
||||
};
|
||||
|
||||
struct sam_passdb_ops *mysql_initialise_sam_password_db(void)
|
||||
{
|
||||
return &sam_mysql_ops;
|
||||
}
|
||||
|
||||
#else
|
||||
void mysql_dummy_sam_function(void) { }
|
||||
#endif
|
@ -70,6 +70,8 @@ BOOL initialise_password_db(void)
|
||||
pwdb_ops = nisplus_initialise_password_db();
|
||||
#elif defined(WITH_LDAP)
|
||||
pwdb_ops = ldap_initialise_password_db();
|
||||
#elif defined(WITH_MYSQL) || defined(WITH_MYSQLSAM)
|
||||
pwdb_ops = mysql_initialise_password_db();
|
||||
#elif defined(USE_SMBPASS_DB)
|
||||
pwdb_ops = file_initialise_password_db();
|
||||
#endif
|
||||
|
@ -70,6 +70,8 @@ BOOL initialise_sam_password_db(void)
|
||||
pwdb_ops = nisplus_initialise_sam_password_db();
|
||||
#elif defined(WITH_LDAP)
|
||||
pwdb_ops = ldap_initialise_sam_password_db();
|
||||
#elif defined(WITH_MYSQLSAM)
|
||||
pwdb_ops = mysql_initialise_sam_password_db();
|
||||
#elif defined(USE_SMBPASS_DB)
|
||||
pwdb_ops = file_initialise_sam_password_db();
|
||||
#endif
|
||||
|
364
source/script/mysql_convert.pl
Normal file
364
source/script/mysql_convert.pl
Normal file
@ -0,0 +1,364 @@
|
||||
#!/usr/local/bin/perl
|
||||
|
||||
use Mysql;
|
||||
|
||||
$ACB_DISABLED=0x0001;
|
||||
$ACB_HOMDIRREQ=0x0002;
|
||||
$ACB_PWNOTREQ=0x0004;
|
||||
$ACB_TEMPDUP=0x0008;
|
||||
$ACB_NORMAL=0x0010;
|
||||
$ACB_MNS=0x0020;
|
||||
$ACB_DOMTRUST=0x0040;
|
||||
$ACB_WSTRUST=0x0080;
|
||||
$ACB_SVRTRUST=0x0100;
|
||||
$ACB_PWNOEXP=0x0200;
|
||||
$ACB_AUTOLOCK=0x0400;
|
||||
|
||||
sub getoptionval {
|
||||
my ($option) = @_;
|
||||
|
||||
my ($value) = ($option =~ /^[^=]+=\s*(\S.*\S)/ );
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
sub usage {
|
||||
|
||||
print <<EOUSAGE;
|
||||
$0 [options]
|
||||
options:
|
||||
--infile=<filename> # smbpasswd style file to read entries from
|
||||
--outfile=<filename> # file to dump results to, format depending
|
||||
# on --infile:
|
||||
# With --infile: Dump mysql script queries
|
||||
# Without --infile: Dump smbpasswd format
|
||||
# from reading mysql database
|
||||
--host=<hostname> # Mysql Server name (default: localhost)
|
||||
--db=<database> # Mysql Database name
|
||||
--user=<user> # Mysql User
|
||||
--password[=<password>] # Mysql password for --user
|
||||
--table=<table> # Mysql table
|
||||
--create # Generate 'create table' query
|
||||
--file=[trash|append] # Action to take if --outfile file exists
|
||||
--check # Do not alter or skip bad uids
|
||||
|
||||
EOUSAGE
|
||||
exit 0;
|
||||
}
|
||||
|
||||
sub getpass {
|
||||
my($prompt)=@_;
|
||||
my($ret);
|
||||
|
||||
print $prompt;
|
||||
system "stty -echo";
|
||||
chomp($ret=<STDIN>);
|
||||
system "stty echo";
|
||||
print "\n";
|
||||
$ret;
|
||||
}
|
||||
|
||||
sub next_entry {
|
||||
my ($name,$uid,$lm,$nt,$f,$lct) = ();
|
||||
|
||||
$name="";
|
||||
if ( not $infile ) {
|
||||
($name,$uid,$lm,$nt,$f,$lct) = $mysqlquery->fetchrow();
|
||||
}
|
||||
else {
|
||||
my $line=<INFILE>;
|
||||
|
||||
return () if ( not $line );
|
||||
|
||||
chomp($line);
|
||||
|
||||
next if ( $line !~ /^[^: ]+:\d+:/ );
|
||||
|
||||
($name,$uid,$lm,$nt,$f,$lct) = split(/:/,$line);
|
||||
|
||||
if ( $lct =~ /^LCT-/ ) {
|
||||
# New Format smbpasswd file
|
||||
my $flags=0;
|
||||
|
||||
$flags |= $ACB_PWNOTREQ if ( $f =~ /N/ );
|
||||
$flags |= $ACB_DISABLED if ( $f =~ /D/ );
|
||||
$flags |= $ACB_HOMDIRREQ if ( $f =~ /H/ );
|
||||
$flags |= $ACB_TEMPDUP if ( $f =~ /T/ );
|
||||
$flags |= $ACB_NORMAL if ( $f =~ /U/ );
|
||||
$flags |= $ACB_MNS if ( $f =~ /M/ );
|
||||
$flags |= $ACB_WSTRUST if ( $f =~ /W/ );
|
||||
$flags |= $ACB_SVRTRUST if ( $f =~ /S/ );
|
||||
$flags |= $ACB_AUTOLOCK if ( $f =~ /L/ );
|
||||
$flags |= $ACB_PWNOEXP if ( $f =~ /X/ );
|
||||
$flags |= $ACB_DOMTRUST if ( $f =~ /I/ );
|
||||
|
||||
$f = $flags;
|
||||
|
||||
$f = $ACB_NORMAL if ( not $f );
|
||||
|
||||
$lct =~ s/LCT-//;
|
||||
$lct = (unpack("L",pack("H8",$lct)))[0];
|
||||
}
|
||||
else {
|
||||
# Old Format smbpasswd file
|
||||
$f = 0;
|
||||
$lct = time();
|
||||
if ( $lm =~ /^NO PASS/ ) {
|
||||
$f |= $ACB_PWNOTREQ;
|
||||
$lm = "";
|
||||
$nt = "";
|
||||
}
|
||||
elsif ( $lm =~ /^XX/ ) {
|
||||
$f |= $ACB_DISABLED;
|
||||
|
||||
$lm = "";
|
||||
$nt = "";
|
||||
}
|
||||
|
||||
if ( $name =~ /\$$/ ) {
|
||||
$f |= $ACB_WSTRUST;
|
||||
}
|
||||
|
||||
$f = $ACB_NORMAL if ( not $f );
|
||||
}
|
||||
}
|
||||
return () if ( not $name );
|
||||
($name,$uid,$lm,$nt,$f,$lct);
|
||||
}
|
||||
|
||||
sub do_query {
|
||||
my ( $query ) = @_;
|
||||
|
||||
chomp($query);
|
||||
if ( $outfile ) {
|
||||
print OUTFILE "$query;\n";
|
||||
}
|
||||
else {
|
||||
if ( not $mysqldb->query($query) ) {
|
||||
print "$query: $Mysql::db_errstr\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub do_file {
|
||||
my ($file,$name,$uid,$lm,$nt,$f,$lct)=@_;
|
||||
|
||||
my $strings = "";
|
||||
|
||||
$strings .= "N" if ( $f & $ACB_PWNOTREQ );
|
||||
$strings .= "D" if ( $f & $ACB_DISABLED );
|
||||
$strings .= "H" if ( $f & $ACB_HOMDIRREQ );
|
||||
$strings .= "T" if ( $f & $ACB_TEMPDUP );
|
||||
$strings .= "U" if ( $f & $ACB_NORMAL );
|
||||
$strings .= "M" if ( $f & $ACB_MNS );
|
||||
$strings .= "W" if ( $f & $ACB_WSTRUST );
|
||||
$strings .= "S" if ( $f & $ACB_SVRTRUST );
|
||||
$strings .= "L" if ( $f & $ACB_AUTOLOCK );
|
||||
$strings .= "X" if ( $f & $ACB_PWNOEXP );
|
||||
$strings .= "I" if ( $f & $ACB_DOMTRUST );
|
||||
|
||||
$f = sprintf( "[%-11s]", $strings );
|
||||
|
||||
$lct=uc("LCT-".(unpack("H8",pack("L","$lct")))[0]);
|
||||
|
||||
$lm = "X"x32 if ( not $lm );
|
||||
$nt = "X"x32 if ( not $nt );
|
||||
|
||||
print $file "$name:$uid:$lm:$nt:$f:$lct\n";
|
||||
}
|
||||
|
||||
$dbhost = "localhost";
|
||||
|
||||
for $option ( @ARGV ) {
|
||||
if ( $option =~ /--outfile=/ ) {
|
||||
$outfile = getoptionval($option);
|
||||
}
|
||||
elsif ( $option =~ /--infile=/ ) {
|
||||
$infile = getoptionval($option);
|
||||
}
|
||||
elsif ( $option =~ /--db=/ ) {
|
||||
$dbname = getoptionval($option);
|
||||
}
|
||||
elsif ( $option =~ /--user=/ ) {
|
||||
$dbuser = getoptionval($option);
|
||||
}
|
||||
elsif ( $option =~ /--host=/ ) {
|
||||
$dbhost = getoptionval($option);
|
||||
}
|
||||
elsif ( $option =~ /--password/ ) {
|
||||
$dbpasswd = getoptionval($option);
|
||||
$need_password = "yes"
|
||||
}
|
||||
elsif ( $option =~ /--table=/ ) {
|
||||
$dbtable = getoptionval($option);
|
||||
}
|
||||
elsif ( $option =~ /--create/ ) {
|
||||
$create_table = "yes";
|
||||
}
|
||||
elsif ( $option =~ /--file=/ ) {
|
||||
$file_action = getoptionval($option);
|
||||
}
|
||||
elsif ( $option =~ /--check/ ) {
|
||||
$check = "yes";
|
||||
}
|
||||
else {
|
||||
print "Unknown option: $option\n";
|
||||
$unknown = "yes";
|
||||
}
|
||||
}
|
||||
|
||||
&usage if ( $unknown eq "yes" );
|
||||
|
||||
if ( ( not $infile ) && ( not $outfile ) && ( $create_table ne "yes" ) ) {
|
||||
print "Need file to read from or write to\n";
|
||||
&usage;
|
||||
}
|
||||
elsif ( $infile && $outfile ) {
|
||||
if ( not $dbtable ) {
|
||||
print "Need --table to create queries\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
# Reading a smbpasswd file, dumping queries into an file which
|
||||
# can be used for a mysql script
|
||||
# --db* options are ignored.
|
||||
|
||||
$ignored = "";
|
||||
$ignored .= " --db" if ( $dbname );
|
||||
$ignored .= " --user" if ( $dbuser );
|
||||
$ignored .= " --password" if ( $dbuser );
|
||||
|
||||
if ( $ignored ) {
|
||||
print "Ignoring options: $ignored\n";
|
||||
}
|
||||
}
|
||||
elsif ( (not $dbname) || (not $dbtable) || (not $dbuser) ) {
|
||||
print "Missing database particulars:\n";
|
||||
print " --db=??\n" if ( not $dbname );
|
||||
print " --user=??\n" if ( not $dbuser );
|
||||
print " --table=??\n" if ( not $dbtable );
|
||||
&usage;
|
||||
}
|
||||
else {
|
||||
if ( ($need_password eq "yes") && ( not $dbpasswd )) {
|
||||
$dbpasswd = getpass("Enter MySQL password for $dbuser: ");
|
||||
}
|
||||
$mysqldb = Connect Mysql($dbhost,$dbname,$dbuser,$dbpasswd);
|
||||
|
||||
if ( not $mysqldb ) {
|
||||
print "Cannot connect to database: $Mysql::db_errstr\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
if ( $outfile ) {
|
||||
$mysqlquery = $mysqldb->query("select unix_name,unix_uid,smb_passwd,smb_nt_passwd,acct_ctrl,pass_last_set_time from $dbtable");
|
||||
|
||||
if ( not $mysqlquery ) {
|
||||
print "MySQL Query failed: $Mysql::db_errstr\n";
|
||||
exit 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( $create_table eq "yes" ) {
|
||||
$create_table_query=<<EOSQL;
|
||||
create table $dbtable (
|
||||
unix_name char(20) not null,
|
||||
unix_uid int(10) unsigned not null,
|
||||
nt_name char(20) not null,
|
||||
user_rid int(10) unsigned not null,
|
||||
smb_passwd char(32),
|
||||
smb_nt_passwd char(32),
|
||||
acct_ctrl int(10) unsigned not null,
|
||||
pass_last_set_time int(10) unsigned not null,
|
||||
unique (unix_name),
|
||||
unique (unix_uid)
|
||||
)
|
||||
EOSQL
|
||||
print "$create_table_query\n";
|
||||
}
|
||||
if ( $infile ) {
|
||||
if ( not open(INFILE,$infile) ) {
|
||||
print "$infile: $!\n";
|
||||
exit 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $outfile ) {
|
||||
if ( ! -f $outfile ) {
|
||||
$open_string=">$outfile";
|
||||
}
|
||||
elsif ( not $file_action ) {
|
||||
print "File $outfile exists:\n";
|
||||
print "Please use --file=[trash|append] option to determine destiny of file\n";
|
||||
exit 1;
|
||||
}
|
||||
elsif ( $file_action eq "append" ) {
|
||||
$open_string = ">>$outfile";
|
||||
}
|
||||
else {
|
||||
$open_string = ">$outfile";
|
||||
}
|
||||
|
||||
if ( not open(OUTFILE,$open_string) ) {
|
||||
print "$outfile: $!\n";
|
||||
exit 1;
|
||||
}
|
||||
}
|
||||
|
||||
do_query($create_table_query) if ( $create_table_query );
|
||||
|
||||
$linenum=1;
|
||||
while (($name,$uid,$lm,$nt,$f,$lct)=next_entry()) {
|
||||
|
||||
$| = 1;
|
||||
print "\r$linenum ";
|
||||
$linenum++;
|
||||
|
||||
$nuid = "";
|
||||
|
||||
$nuid = (getpwnam(lc($name)))[2];
|
||||
|
||||
if ( $check ) {
|
||||
if ( not $nuid ) {
|
||||
# print "Removing $name: Does not exist\n";
|
||||
push(@removed,[$name,$uid,$lm,$nt,$f,$lct]);
|
||||
next;
|
||||
}
|
||||
else {
|
||||
# print "Changing uid of $name\n";
|
||||
$uid = $nuid;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $infile ) {
|
||||
if ( $lm ) {
|
||||
$lm = "'$lm'";
|
||||
}
|
||||
else {
|
||||
$lm = "NULL";
|
||||
}
|
||||
if ( $nt ) {
|
||||
$nt = "'$nt'";
|
||||
}
|
||||
else {
|
||||
$nt = "NULL";
|
||||
}
|
||||
$rid=(4*$uid)+1000;
|
||||
do_query("insert into $dbtable (unix_name,unix_uid,smb_passwd,smb_nt_passwd,acct_ctrl,pass_last_set_time,nt_name,user_rid) values ('$name',$uid,$lm,$nt,$f,$lct,'$name',$rid)");
|
||||
}
|
||||
else {
|
||||
do_file(OUTFILE,$name,$uid,$lm,$nt,$f,$lct);
|
||||
}
|
||||
}
|
||||
|
||||
if ( @removed ) {
|
||||
print "\n\nIgnored entries because usernames do not exist\n";
|
||||
foreach $line ( @removed ) {
|
||||
do_file(STDOUT,@{ $line });
|
||||
}
|
||||
}
|
||||
|
||||
close (OUTFILE) if ( $outfile );
|
||||
close (INFILE) if ( $infile );
|
||||
print "\n";
|
Loading…
Reference in New Issue
Block a user