📄 pdb_pgsql.c
字号:
/* * PostgresSQL password backend for samba * Copyright (C) Hamish Friedlander 2003 * Copyright (C) Jelmer Vernooij 2004 * * 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 <libpq-fe.h>#define CONFIG_HOST_DEFAULT "localhost"#define CONFIG_USER_DEFAULT "samba"#define CONFIG_PASS_DEFAULT ""#define CONFIG_PORT_DEFAULT "5432"#define CONFIG_DB_DEFAULT "samba"/* handles for doing db transactions */typedef struct pdb_pgsql_data { PGconn *master_handle ; PGconn *handle ; PGresult *pwent ; long currow ; const char *db ; const char *host ; const char *port ; const char *user ; const char *pass ; const char *location ;} pdb_pgsql_data ;struct pdb_context *the_pdb_context;#define SET_DATA(data,methods) { \ if(!methods){ \ DEBUG(0, ("invalid methods!\n")); \ return NT_STATUS_INVALID_PARAMETER; \ } \ data = (struct pdb_pgsql_data *)methods->private_data; \}#define SET_DATA_QUIET(data,methods) { \ if(!methods){ \ DEBUG(0, ("invalid methods!\n")); \ return ; \ } \ data = (struct pdb_pgsql_data *)methods->private_data; \}#define config_value( data, name, default_value ) \ lp_parm_const_string( GLOBAL_SECTION_SNUM, (data)->location, name, default_value )static PGconn *pgsqlsam_connect( struct pdb_pgsql_data *data ){ PGconn *handle; DEBUG ( 1, ( "Connecting to database server, host: %s, user: %s, password: XXXXXX, database: %s, port: %s\n", data->host, data->user, data->db, data->port ) ) ; /* Do the pgsql initialization */ handle = PQsetdbLogin( data->host, data->port, NULL, NULL, data->db, data->user, data->pass ) ; if ( handle != NULL && PQstatus( handle ) != CONNECTION_OK ) { DEBUG( 0, ("Failed to connect to pgsql database: error: %s\n", (handle != NULL ? PQerrorMessage( handle ) : "")) ) ; return NULL; } DEBUG( 5, ("Connected to pgsql database\n") ) ; return handle;}/* The assumption here is that the master process will get connection 0, * and all the renaining ones just one connection for their etire life span. */static PGconn *choose_connection( struct pdb_pgsql_data *data ){ if ( data->master_handle == NULL ) { data->master_handle = pgsqlsam_connect( data ); return data->master_handle ; } /* Master connection != NULL, so we are just another process. */ /* If we didn't connect yet, do it now. */ if ( data->handle == NULL ) { data->handle = pgsqlsam_connect( data ); } return data->handle ;}static long PQgetlong( PGresult *r, long row, long col ){ if ( PQgetisnull( r, row, col ) ) return 0 ; return atol( PQgetvalue( r, row, col ) ) ;}static NTSTATUS row_to_sam_account ( PGresult *r, long row, SAM_ACCOUNT *u ){ pstring temp ; DOM_SID sid ; unsigned char *hours ; size_t hours_len = 0 ; if ( row >= PQntuples( r ) ) return NT_STATUS_INVALID_PARAMETER ; pdb_set_logon_time ( u, PQgetlong ( r, row, 0 ), PDB_SET ) ; pdb_set_logoff_time ( u, PQgetlong ( r, row, 1 ), PDB_SET ) ; pdb_set_kickoff_time ( u, PQgetlong ( r, row, 2 ), PDB_SET ) ; pdb_set_pass_last_set_time ( u, PQgetlong ( r, row, 3 ), PDB_SET ) ; pdb_set_pass_can_change_time ( u, PQgetlong ( r, row, 4 ), PDB_SET ) ; pdb_set_pass_must_change_time( u, PQgetlong ( r, row, 5 ), PDB_SET ) ; pdb_set_username ( u, PQgetvalue( r, row, 6 ), PDB_SET ) ; pdb_set_domain ( u, PQgetvalue( r, row, 7 ), PDB_SET ) ; pdb_set_nt_username ( u, PQgetvalue( r, row, 8 ), PDB_SET ) ; pdb_set_fullname ( u, PQgetvalue( r, row, 9 ), PDB_SET ) ; pdb_set_homedir ( u, PQgetvalue( r, row, 10 ), PDB_SET ) ; pdb_set_dir_drive ( u, PQgetvalue( r, row, 11 ), PDB_SET ) ; pdb_set_logon_script ( u, PQgetvalue( r, row, 12 ), PDB_SET ) ; pdb_set_profile_path ( u, PQgetvalue( r, row, 13 ), PDB_SET ) ; pdb_set_acct_desc ( u, PQgetvalue( r, row, 14 ), PDB_SET ) ; pdb_set_workstations ( u, PQgetvalue( r, row, 15 ), PDB_SET ) ; pdb_set_unknown_str ( u, PQgetvalue( r, row, 16 ), PDB_SET ) ; pdb_set_munged_dial ( u, PQgetvalue( r, row, 17 ), PDB_SET ) ; pdb_set_acct_ctrl ( u, PQgetlong ( r, row, 23 ), PDB_SET ) ; pdb_set_logon_divs ( u, PQgetlong ( r, row, 24 ), PDB_SET ) ; pdb_set_hours_len ( u, PQgetlong ( r, row, 25 ), PDB_SET ) ; pdb_set_bad_password_count ( u, PQgetlong ( r, row, 26 ), PDB_SET ) ; pdb_set_logon_count ( u, PQgetlong ( r, row, 27 ), PDB_SET ) ; pdb_set_unknown_6 ( u, PQgetlong ( r, row, 28 ), PDB_SET ) ; hours = PQgetvalue ( r, row, 29 ); if ( hours != NULL ) { hours = PQunescapeBytea ( hours, &hours_len ) ; if ( hours_len > 0 ) pdb_set_hours ( u, hours, PDB_SET ) ; free ( hours ); } if ( !PQgetisnull( r, row, 18 ) ) { string_to_sid( &sid, PQgetvalue( r, row, 18 ) ) ; pdb_set_user_sid ( u, &sid, PDB_SET ) ; } if ( !PQgetisnull( r, row, 19 ) ) { string_to_sid( &sid, PQgetvalue( r, row, 19 ) ) ; pdb_set_group_sid( u, &sid, PDB_SET ) ; } if ( pdb_gethexpwd( PQgetvalue( r, row, 20 ), temp ), PDB_SET ) pdb_set_lanman_passwd( u, temp, PDB_SET ) ; if ( pdb_gethexpwd( PQgetvalue( r, row, 21 ), temp ), PDB_SET ) pdb_set_nt_passwd ( u, temp, PDB_SET ) ; /* Only use plaintext password storage when lanman and nt are NOT used */ if ( PQgetisnull( r, row, 20 ) || PQgetisnull( r, row, 21 ) ) pdb_set_plaintext_passwd( u, PQgetvalue( r, row, 22 ) ) ; return NT_STATUS_OK ;}static NTSTATUS pgsqlsam_setsampwent(struct pdb_methods *methods, BOOL update, uint16 acb_mask){ struct pdb_pgsql_data *data ; PGconn *handle ; char *query ; NTSTATUS retval ; SET_DATA( data, methods ) ; /* Connect to the DB. */ handle = choose_connection( data ); if ( handle == NULL ) return NT_STATUS_UNSUCCESSFUL ; DEBUG( 5, ("CONNECTING pgsqlsam_setsampwent\n") ) ; query = sql_account_query_select(NULL, data->location, update, SQL_SEARCH_NONE, NULL); /* Do it */ DEBUG( 5, ("Executing query %s\n", query) ) ; data->pwent = PQexec( handle, query ) ; data->currow = 0 ; /* Result? */ if ( data->pwent == NULL ) { DEBUG( 0, ("Error executing %s, %s\n", query, PQerrorMessage( handle ) ) ) ; retval = NT_STATUS_UNSUCCESSFUL ; } else if ( PQresultStatus( data->pwent ) != PGRES_TUPLES_OK ) { DEBUG( 0, ("Error executing %s, %s\n", query, PQresultErrorMessage( data->pwent ) ) ) ; retval = NT_STATUS_UNSUCCESSFUL ; } else { DEBUG( 5, ("pgsqlsam_setsampwent succeeded(%d results)!\n", PQntuples(data->pwent)) ) ; retval = NT_STATUS_OK ; } talloc_free(query); return retval ;}/*************************************************************** End enumeration of the passwd list. ****************************************************************/static void pgsqlsam_endsampwent(struct pdb_methods *methods){ struct pdb_pgsql_data *data ; SET_DATA_QUIET( data, methods ) ; if (data->pwent != NULL) { PQclear( data->pwent ) ; } data->pwent = NULL ; data->currow = 0 ; DEBUG( 5, ("pgsql_endsampwent called\n") ) ;}/***************************************************************** Get one SAM_ACCOUNT from the list (next in line) *****************************************************************/static NTSTATUS pgsqlsam_getsampwent( struct pdb_methods *methods, SAM_ACCOUNT *user ){ struct pdb_pgsql_data *data; NTSTATUS retval ; SET_DATA( data, methods ) ; if ( data->pwent == NULL ) { DEBUG( 0, ("invalid pwent\n") ) ; return NT_STATUS_INVALID_PARAMETER ; } retval = row_to_sam_account( data->pwent, data->currow, user ) ; data->currow++ ; return retval ;}static NTSTATUS pgsqlsam_select_by_field ( struct pdb_methods *methods, SAM_ACCOUNT *user, enum sql_search_field field, const char *sname ){ struct pdb_pgsql_data *data ; PGconn *handle ; char *esc ; char *query ; PGresult *result ; NTSTATUS retval ; SET_DATA(data, methods); if ( user == NULL ) { DEBUG( 0, ("pdb_getsampwnam: SAM_ACCOUNT is NULL.\n") ) ; return NT_STATUS_INVALID_PARAMETER; } DEBUG( 5, ("pgsqlsam_select_by_field: getting data where %d = %s(nonescaped)\n", field, sname) ) ; /* Escape sname */ esc = talloc_array(NULL, char, strlen(sname) * 2 + 1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -