1
0
mirror of https://github.com/samba-team/samba.git synced 2025-11-22 16:23:49 +03:00

Remove pstring from everything in rpc_server except

srv_spoolss_nt.c and srv_srvsvc_nt.c.
They're next :-).
Jeremy.
This commit is contained in:
Jeremy Allison
2007-11-27 11:22:58 -08:00
parent 172f7ce96d
commit 55b4f9d003
8 changed files with 360 additions and 270 deletions

View File

@@ -134,15 +134,15 @@ typedef struct {
typedef struct { typedef struct {
uint32 source_name_len; uint32 source_name_len;
wpstring source_name; smb_ucs2_t *source_name;
uint32 computer_name_len; uint32 computer_name_len;
wpstring computer_name; smb_ucs2_t *computer_name;
uint32 sid_padding; uint32 sid_padding;
wpstring sid; smb_ucs2_t *sid;
uint32 strings_len; uint32 strings_len;
wpstring strings; smb_ucs2_t *strings;
uint32 user_data_len; uint32 user_data_len;
pstring user_data; char *user_data;
uint32 data_padding; uint32 data_padding;
} Eventlog_data_record; } Eventlog_data_record;

View File

@@ -62,17 +62,16 @@ TDB_CONTEXT *elog_init_tdb( char *tdbfilename )
and size. Caller must free memory. and size. Caller must free memory.
********************************************************************/ ********************************************************************/
char *elog_tdbname( const char *name ) char *elog_tdbname(TALLOC_CTX *ctx, const char *name )
{ {
fstring path; char *path = talloc_asprintf(ctx, "%s/%s.tdb",
char *tdb_fullpath; state_path("eventlog"),
char *eventlogdir = state_path( "eventlog" ); name);
if (!path) {
pstr_sprintf( path, "%s/%s.tdb", eventlogdir, name ); return NULL;
strlower_m( path ); }
tdb_fullpath = SMB_STRDUP( path ); strlower_m(path);
return path;
return tdb_fullpath;
} }
@@ -320,13 +319,13 @@ ELOG_TDB *elog_open_tdb( char *logname, bool force_clear )
TDB_CONTEXT *tdb = NULL; TDB_CONTEXT *tdb = NULL;
uint32 vers_id; uint32 vers_id;
ELOG_TDB *ptr; ELOG_TDB *ptr;
char *tdbfilename; char *tdbpath = NULL;
pstring tdbpath;
ELOG_TDB *tdb_node = NULL; ELOG_TDB *tdb_node = NULL;
char *eventlogdir; char *eventlogdir;
TALLOC_CTX *ctx = talloc_tos();
/* first see if we have an open context */ /* first see if we have an open context */
for ( ptr=open_elog_list; ptr; ptr=ptr->next ) { for ( ptr=open_elog_list; ptr; ptr=ptr->next ) {
if ( strequal( ptr->name, logname ) ) { if ( strequal( ptr->name, logname ) ) {
ptr->ref_count++; ptr->ref_count++;
@@ -345,27 +344,28 @@ ELOG_TDB *elog_open_tdb( char *logname, bool force_clear )
return ptr; return ptr;
} }
} }
/* make sure that the eventlog dir exists */ /* make sure that the eventlog dir exists */
eventlogdir = state_path( "eventlog" ); eventlogdir = state_path( "eventlog" );
if ( !directory_exist( eventlogdir, NULL ) ) if ( !directory_exist( eventlogdir, NULL ) )
mkdir( eventlogdir, 0755 ); mkdir( eventlogdir, 0755 );
/* get the path on disk */
tdbfilename = elog_tdbname( logname );
pstrcpy( tdbpath, tdbfilename );
SAFE_FREE( tdbfilename );
DEBUG(7,("elog_open_tdb: Opening %s...(force_clear == %s)\n", /* get the path on disk */
tdbpath = elog_tdbname(ctx, logname);
if (!tdbpath) {
return NULL;
}
DEBUG(7,("elog_open_tdb: Opening %s...(force_clear == %s)\n",
tdbpath, force_clear?"True":"False" )); tdbpath, force_clear?"True":"False" ));
/* the tdb wasn't already open or this is a forced clear open */ /* the tdb wasn't already open or this is a forced clear open */
if ( !force_clear ) { if ( !force_clear ) {
tdb = tdb_open_log( tdbpath, 0, TDB_DEFAULT, O_RDWR , 0 ); tdb = tdb_open_log( tdbpath, 0, TDB_DEFAULT, O_RDWR , 0 );
if ( tdb ) { if ( tdb ) {
vers_id = tdb_fetch_int32( tdb, EVT_VERSION ); vers_id = tdb_fetch_int32( tdb, EVT_VERSION );
@@ -593,9 +593,8 @@ void fixup_eventlog_entry( Eventlog_entry * ee )
bool parse_logentry( char *line, Eventlog_entry * entry, bool * eor ) bool parse_logentry( char *line, Eventlog_entry * entry, bool * eor )
{ {
TALLOC_CTX *ctx = talloc_tos();
char *start = NULL, *stop = NULL; char *start = NULL, *stop = NULL;
pstring temp;
int temp_len = 0;
start = line; start = line;
@@ -661,62 +660,69 @@ bool parse_logentry( char *line, Eventlog_entry * entry, bool * eor )
} else if ( 0 == strncmp( start, "USL", stop - start ) ) { } else if ( 0 == strncmp( start, "USL", stop - start ) ) {
entry->record.user_sid_length = atoi( stop + 1 ); entry->record.user_sid_length = atoi( stop + 1 );
} else if ( 0 == strncmp( start, "SRC", stop - start ) ) { } else if ( 0 == strncmp( start, "SRC", stop - start ) ) {
memset( temp, 0, sizeof( temp ) );
stop++; stop++;
while ( isspace( stop[0] ) ) { while ( isspace( stop[0] ) ) {
stop++; stop++;
} }
temp_len = strlen( stop ); entry->data_record.source_name_len = rpcstr_push_talloc(ctx,
strncpy( temp, stop, temp_len ); &entry->data_record.source_name,
rpcstr_push( ( void * ) ( entry->data_record.source_name ), stop);
temp, sizeof( entry->data_record.source_name ), if (entry->data_record.source_name_len == (size_t)-1 ||
STR_TERMINATE ); entry->data_record.source_name == NULL) {
entry->data_record.source_name_len = return false;
( strlen_w( entry->data_record.source_name ) * 2 ) + }
2;
} else if ( 0 == strncmp( start, "SRN", stop - start ) ) { } else if ( 0 == strncmp( start, "SRN", stop - start ) ) {
memset( temp, 0, sizeof( temp ) );
stop++; stop++;
while ( isspace( stop[0] ) ) { while ( isspace( stop[0] ) ) {
stop++; stop++;
} }
temp_len = strlen( stop ); entry->data_record.computer_name_len = rpcstr_push_talloc(ctx,
strncpy( temp, stop, temp_len ); &entry->data_record.computer_name,
rpcstr_push( ( void * ) ( entry->data_record.computer_name ), stop);
temp, sizeof( entry->data_record.computer_name ), if (entry->data_record.computer_name_len == (size_t)-1 ||
STR_TERMINATE ); entry->data_record.computer_name == NULL) {
entry->data_record.computer_name_len = return false;
( strlen_w( entry->data_record.computer_name ) * 2 ) + }
2;
} else if ( 0 == strncmp( start, "SID", stop - start ) ) { } else if ( 0 == strncmp( start, "SID", stop - start ) ) {
memset( temp, 0, sizeof( temp ) );
stop++; stop++;
while ( isspace( stop[0] ) ) { while ( isspace( stop[0] ) ) {
stop++; stop++;
} }
temp_len = strlen( stop ); entry->record.user_sid_length = rpcstr_push_talloc(ctx,
strncpy( temp, stop, temp_len ); &entry->data_record.sid,
rpcstr_push( ( void * ) ( entry->data_record.sid ), temp, stop);
sizeof( entry->data_record.sid ), if (entry->record.user_sid_length == (size_t)-1 ||
STR_TERMINATE ); entry->data_record.sid == NULL) {
entry->record.user_sid_length = return false;
( strlen_w( entry->data_record.sid ) * 2 ) + 2; }
} else if ( 0 == strncmp( start, "STR", stop - start ) ) { } else if ( 0 == strncmp( start, "STR", stop - start ) ) {
smb_ucs2_t *temp = NULL;
size_t tmp_len;
uint32_t old_len;
/* skip past initial ":" */ /* skip past initial ":" */
stop++; stop++;
/* now skip any other leading whitespace */ /* now skip any other leading whitespace */
while ( isspace( stop[0] ) ) { while ( isspace(stop[0])) {
stop++; stop++;
} }
temp_len = strlen( stop ); tmp_len = rpcstr_push_talloc(ctx,
memset( temp, 0, sizeof( temp ) ); &temp,
strncpy( temp, stop, temp_len ); stop);
rpcstr_push( ( void * ) ( entry->data_record.strings + if (tmp_len == (size_t)-1 || !temp) {
( entry->data_record.strings_len / 2 ) ), return false;
temp, }
sizeof( entry->data_record.strings ) - old_len = entry->data_record.strings_len;
( entry->data_record.strings_len / 2 ), STR_TERMINATE ); entry->data_record.strings = (smb_ucs2_t *)TALLOC_REALLOC_ARRAY(ctx,
entry->data_record.strings_len += ( temp_len * 2 ) + 2; entry->data_record.strings,
char,
old_len + tmp_len);
if (!entry->data_record.strings) {
return false;
}
memcpy(entry->data_record.strings + old_len,
temp,
tmp_len);
entry->data_record.strings_len += tmp_len;
entry->record.num_strings++; entry->record.num_strings++;
} else if ( 0 == strncmp( start, "DAT", stop - start ) ) { } else if ( 0 == strncmp( start, "DAT", stop - start ) ) {
/* skip past initial ":" */ /* skip past initial ":" */
@@ -725,25 +731,18 @@ bool parse_logentry( char *line, Eventlog_entry * entry, bool * eor )
while ( isspace( stop[0] ) ) { while ( isspace( stop[0] ) ) {
stop++; stop++;
} }
entry->data_record.user_data_len = strlen( stop ); entry->data_record.user_data_len = strlen(stop);
memset( entry->data_record.user_data, 0, entry->data_record.user_data = talloc_strdup(ctx,
sizeof( entry->data_record.user_data ) ); stop);
if ( entry->data_record.user_data_len > 0 ) { if (!entry->data_record.user_data) {
/* copy no more than the first 1024 bytes */ return false;
if ( entry->data_record.user_data_len >
sizeof( entry->data_record.user_data ) )
entry->data_record.user_data_len =
sizeof( entry->data_record.
user_data );
memcpy( entry->data_record.user_data, stop,
entry->data_record.user_data_len );
} }
} else { } else {
/* some other eventlog entry -- not implemented, so dropping on the floor */ /* some other eventlog entry -- not implemented, so dropping on the floor */
DEBUG( 10, ( "Unknown entry [%s]. Ignoring.\n", line ) ); DEBUG( 10, ( "Unknown entry [%s]. Ignoring.\n", line ) );
/* For now return true so that we can keep on parsing this mess. Eventually /* For now return true so that we can keep on parsing this mess. Eventually
we will return False here. */ we will return False here. */
return True; return true;
} }
return True; return true;
} }

View File

@@ -69,7 +69,7 @@ static EVENTLOG_INFO *find_eventlog_info_by_hnd( pipes_struct * p,
static bool elog_check_access( EVENTLOG_INFO *info, NT_USER_TOKEN *token ) static bool elog_check_access( EVENTLOG_INFO *info, NT_USER_TOKEN *token )
{ {
char *tdbname = elog_tdbname( info->logname ); char *tdbname = elog_tdbname(talloc_tos(), info->logname );
SEC_DESC *sec_desc; SEC_DESC *sec_desc;
bool ret; bool ret;
NTSTATUS ntstatus; NTSTATUS ntstatus;
@@ -280,22 +280,28 @@ static int elog_size( EVENTLOG_INFO *info )
} }
/******************************************************************** /********************************************************************
For the given tdb, get the next eventlog record into the passed For the given tdb, get the next eventlog record into the passed
Eventlog_entry. returns NULL if it can't get the record for some reason. Eventlog_entry. returns NULL if it can't get the record for some reason.
********************************************************************/ ********************************************************************/
static Eventlog_entry *get_eventlog_record( prs_struct * ps, TDB_CONTEXT * tdb, static Eventlog_entry *get_eventlog_record(prs_struct *ps,
int recno, Eventlog_entry * ee ) TDB_CONTEXT *tdb,
int recno)
{ {
Eventlog_entry *ee = NULL;
TDB_DATA ret, key; TDB_DATA ret, key;
int srecno; int srecno;
int reclen; int reclen;
int len; int len;
pstring *wpsource, *wpcomputer, *wpsid, *wpstrs, *puserdata; char *wpsource = NULL;
char *wpcomputer = NULL;
char *wpsid = NULL;
char *wpstrs = NULL;
char *puserdata = NULL;
key.dsize = sizeof( int32 ); key.dsize = sizeof(int32);
srecno = recno; srecno = recno;
key.dptr = ( uint8 * ) &srecno; key.dptr = ( uint8 * ) &srecno;
@@ -316,10 +322,11 @@ static Eventlog_entry *get_eventlog_record( prs_struct * ps, TDB_CONTEXT * tdb,
if ( !len ) if ( !len )
return NULL; return NULL;
/* ee = PRS_ALLOC_MEM(ps, Eventlog_entry, 1); */ ee = TALLOC_ARRAY(ps->mem_ctx, Eventlog_entry, 1);
if (!ee) {
if ( !ee )
return NULL; return NULL;
}
ZERO_STRUCTP(ee);
len = tdb_unpack( ret.dptr, ret.dsize, "ddddddwwwwddddddBBdBBBd", len = tdb_unpack( ret.dptr, ret.dsize, "ddddddwwwwddddddBBdBBBd",
&ee->record.length, &ee->record.reserved1, &ee->record.length, &ee->record.reserved1,
@@ -347,36 +354,67 @@ static Eventlog_entry *get_eventlog_record( prs_struct * ps, TDB_CONTEXT * tdb,
/* have to do the following because the tdb_unpack allocs a buff, stuffs a pointer to the buff /* have to do the following because the tdb_unpack allocs a buff, stuffs a pointer to the buff
into it's 2nd argment for 'B' */ into it's 2nd argment for 'B' */
if ( wpcomputer ) if (wpcomputer) {
memcpy( ee->data_record.computer_name, wpcomputer, ee->data_record.computer_name = TALLOC_MEMDUP(ee,
ee->data_record.computer_name_len ); wpcomputer,
if ( wpsource ) ee->data_record.computer_name_len);
memcpy( ee->data_record.source_name, wpsource, if (!ee->data_record.computer_name) {
ee->data_record.source_name_len ); TALLOC_FREE(ee);
goto out;
}
}
if (wpsource) {
ee->data_record.source_name = TALLOC_MEMDUP(ee,
wpsource,
ee->data_record.source_name_len);
if (!ee->data_record.source_name) {
TALLOC_FREE(ee);
goto out;
}
}
if ( wpsid ) if (wpsid) {
memcpy( ee->data_record.sid, wpsid, ee->data_record.sid = TALLOC_MEMDUP(ee,
ee->record.user_sid_length ); wpsid,
if ( wpstrs ) ee->record.user_sid_length);
memcpy( ee->data_record.strings, wpstrs, if (!ee->data_record.sid) {
ee->data_record.strings_len ); TALLOC_FREE(ee);
goto out;
}
}
if (wpstrs) {
ee->data_record.strings = TALLOC_MEMDUP(ee,
wpstrs,
ee->data_record.strings_len);
if (!ee->data_record.strings) {
TALLOC_FREE(ee);
goto out;
}
}
/* note that userdata is a pstring */ if (puserdata) {
if ( puserdata ) ee->data_record.user_data = TALLOC_MEMDUP(ee,
memcpy( ee->data_record.user_data, puserdata, puserdata,
ee->data_record.user_data_len ); ee->data_record.user_data_len);
if (!ee->data_record.user_data) {
TALLOC_FREE(ee);
goto out;
}
}
SAFE_FREE( wpcomputer ); out:
SAFE_FREE( wpsource );
SAFE_FREE( wpsid ); SAFE_FREE(wpcomputer);
SAFE_FREE( wpstrs ); SAFE_FREE(wpsource);
SAFE_FREE( puserdata ); SAFE_FREE(wpsid);
SAFE_FREE(wpstrs);
SAFE_FREE(puserdata);
DEBUG( 10, ( "get_eventlog_record: read back %d\n", len ) ); DEBUG( 10, ( "get_eventlog_record: read back %d\n", len ) );
DEBUG( 10, DEBUG( 10,
( "get_eventlog_record: computer_name %d is ", ( "get_eventlog_record: computer_name %d is ",
ee->data_record.computer_name_len ) ); ee->data_record.computer_name_len ) );
SAFE_FREE( ret.dptr ); SAFE_FREE(ret.dptr);
return ee; return ee;
} }
@@ -387,7 +425,7 @@ static Eventlog_entry *get_eventlog_record( prs_struct * ps, TDB_CONTEXT * tdb,
static bool sync_eventlog_params( EVENTLOG_INFO *info ) static bool sync_eventlog_params( EVENTLOG_INFO *info )
{ {
pstring path; char *path = NULL;
uint32 uiMaxSize; uint32 uiMaxSize;
uint32 uiRetention; uint32 uiRetention;
REGISTRY_KEY *keyinfo; REGISTRY_KEY *keyinfo;
@@ -395,6 +433,7 @@ static bool sync_eventlog_params( EVENTLOG_INFO *info )
REGVAL_CTR *values; REGVAL_CTR *values;
WERROR wresult; WERROR wresult;
char *elogname = info->logname; char *elogname = info->logname;
TALLOC_CTX *ctx = talloc_tos();
DEBUG( 4, ( "sync_eventlog_params with %s\n", elogname ) ); DEBUG( 4, ( "sync_eventlog_params with %s\n", elogname ) );
@@ -412,7 +451,10 @@ static bool sync_eventlog_params( EVENTLOG_INFO *info )
to use the same fetch/store api that we use in to use the same fetch/store api that we use in
srv_reg_nt.c */ srv_reg_nt.c */
pstr_sprintf( path, "%s/%s", KEY_EVENTLOG, elogname ); path = talloc_asprintf(ctx, "%s/%s", KEY_EVENTLOG, elogname );
if (!path) {
return false;
}
wresult = regkey_open_internal( NULL, &keyinfo, path, wresult = regkey_open_internal( NULL, &keyinfo, path,
get_root_nt_token( ), REG_KEY_READ ); get_root_nt_token( ), REG_KEY_READ );
@@ -624,16 +666,20 @@ NTSTATUS _eventlog_clear_eventlog( pipes_struct * p,
EVENTLOG_R_CLEAR_EVENTLOG * r_u ) EVENTLOG_R_CLEAR_EVENTLOG * r_u )
{ {
EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, &q_u->handle ); EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, &q_u->handle );
pstring backup_file_name; char *backup_file_name = NULL;
if ( !info ) if ( !info )
return NT_STATUS_INVALID_HANDLE; return NT_STATUS_INVALID_HANDLE;
pstrcpy( backup_file_name, "" ); if (q_u->backupfile.string) {
if ( q_u->backupfile.string ) { size_t len = rpcstr_pull_talloc(p->mem_ctx,
rpcstr_pull( backup_file_name, q_u->backupfile.string->buffer, &backup_file_name,
sizeof( backup_file_name ), q_u->backupfile.string->buffer,
q_u->backupfile.string->uni_str_len * 2, 0 ); q_u->backupfile.string->uni_str_len * 2,
0 );
if (len == (size_t)-1 || !backup_file_name) {
return NT_STATUS_INVALID_PARAMETER;
}
DEBUG(8,( "_eventlog_clear_eventlog: Using [%s] as the backup " DEBUG(8,( "_eventlog_clear_eventlog: Using [%s] as the backup "
"file name for log [%s].", "file name for log [%s].",
@@ -647,7 +693,7 @@ NTSTATUS _eventlog_clear_eventlog( pipes_struct * p,
/* Force a close and reopen */ /* Force a close and reopen */
elog_close_tdb( info->etdb, True ); elog_close_tdb( info->etdb, True );
become_root(); become_root();
info->etdb = elog_open_tdb( info->logname, True ); info->etdb = elog_open_tdb( info->logname, True );
unbecome_root(); unbecome_root();
@@ -674,7 +720,7 @@ NTSTATUS _eventlog_read_eventlog( pipes_struct * p,
EVENTLOG_R_READ_EVENTLOG * r_u ) EVENTLOG_R_READ_EVENTLOG * r_u )
{ {
EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, &q_u->handle ); EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, &q_u->handle );
Eventlog_entry entry, *ee_new; Eventlog_entry *entry = NULL, *ee_new = NULL;
uint32 num_records_read = 0; uint32 num_records_read = 0;
prs_struct *ps; prs_struct *ps;
int bytes_left, record_number; int bytes_left, record_number;
@@ -689,9 +735,9 @@ NTSTATUS _eventlog_read_eventlog( pipes_struct * p,
bytes_left = q_u->max_read_size; bytes_left = q_u->max_read_size;
if ( !info->etdb ) if ( !info->etdb )
return NT_STATUS_ACCESS_DENIED; return NT_STATUS_ACCESS_DENIED;
/* check for valid flags. Can't use the sequential and seek flags together */ /* check for valid flags. Can't use the sequential and seek flags together */
elog_read_type = q_u->flags & (EVENTLOG_SEQUENTIAL_READ|EVENTLOG_SEEK_READ); elog_read_type = q_u->flags & (EVENTLOG_SEQUENTIAL_READ|EVENTLOG_SEEK_READ);
@@ -708,37 +754,39 @@ NTSTATUS _eventlog_read_eventlog( pipes_struct * p,
if ( elog_read_type & EVENTLOG_SEQUENTIAL_READ ) if ( elog_read_type & EVENTLOG_SEQUENTIAL_READ )
record_number = info->current_record; record_number = info->current_record;
else else
record_number = q_u->offset; record_number = q_u->offset;
while ( bytes_left > 0 ) { while ( bytes_left > 0 ) {
/* assume that when the record fetch fails, that we are done */ /* assume that when the record fetch fails, that we are done */
if ( !get_eventlog_record ( ps, ELOG_TDB_CTX(info->etdb), record_number, &entry ) ) entry = get_eventlog_record (ps, ELOG_TDB_CTX(info->etdb), record_number);
if (!entry) {
break; break;
}
DEBUG( 8, ( "Retrieved record %d\n", record_number ) ); DEBUG( 8, ( "Retrieved record %d\n", record_number ) );
/* Now see if there is enough room to add */ /* Now see if there is enough room to add */
if ( !(ee_new = read_package_entry( ps, q_u, r_u,&entry )) ) if ( !(ee_new = read_package_entry( ps, q_u, r_u, entry )) )
return NT_STATUS_NO_MEMORY; return NT_STATUS_NO_MEMORY;
if ( r_u->num_bytes_in_resp + ee_new->record.length > q_u->max_read_size ) { if ( r_u->num_bytes_in_resp + ee_new->record.length > q_u->max_read_size ) {
r_u->bytes_in_next_record = ee_new->record.length; r_u->bytes_in_next_record = ee_new->record.length;
/* response would be too big to fit in client-size buffer */ /* response would be too big to fit in client-size buffer */
bytes_left = 0; bytes_left = 0;
break; break;
} }
add_record_to_resp( r_u, ee_new ); add_record_to_resp( r_u, ee_new );
bytes_left -= ee_new->record.length; bytes_left -= ee_new->record.length;
ZERO_STRUCT( entry ); TALLOC_FREE(entry);
num_records_read = r_u->num_records - num_records_read; num_records_read = r_u->num_records - num_records_read;
DEBUG( 10, ( "_eventlog_read_eventlog: read [%d] records for a total " DEBUG( 10, ( "_eventlog_read_eventlog: read [%d] records for a total "
"of [%d] records using [%d] bytes out of a max of [%d].\n", "of [%d] records using [%d] bytes out of a max of [%d].\n",
num_records_read, r_u->num_records, num_records_read, r_u->num_records,
@@ -749,13 +797,13 @@ NTSTATUS _eventlog_read_eventlog( pipes_struct * p,
record_number++; record_number++;
else else
record_number--; record_number--;
/* update the eventlog record pointer */ /* update the eventlog record pointer */
info->current_record = record_number; info->current_record = record_number;
} }
/* crazy by WinXP uses NT_STATUS_BUFFER_TOO_SMALL to /* crazy by WinXP uses NT_STATUS_BUFFER_TOO_SMALL to
say when there are no more records */ say when there are no more records */
return (num_records_read ? NT_STATUS_OK : NT_STATUS_BUFFER_TOO_SMALL); return (num_records_read ? NT_STATUS_OK : NT_STATUS_BUFFER_TOO_SMALL);

View File

@@ -948,16 +948,16 @@ static NTSTATUS _net_sam_logon_internal(pipes_struct *p,
/* This is the point at which, if the login was successful, that /* This is the point at which, if the login was successful, that
the SAM Local Security Authority should record that the user is the SAM Local Security Authority should record that the user is
logged in to the domain. */ logged in to the domain. */
{ {
DOM_GID *gids = NULL; DOM_GID *gids = NULL;
const DOM_SID *user_sid = NULL; const DOM_SID *user_sid = NULL;
const DOM_SID *group_sid = NULL; const DOM_SID *group_sid = NULL;
DOM_SID domain_sid; DOM_SID domain_sid;
uint32 user_rid, group_rid; uint32 user_rid, group_rid;
int num_gids = 0; int num_gids = 0;
pstring my_name; const char *my_name;
fstring user_sid_string; fstring user_sid_string;
fstring group_sid_string; fstring group_sid_string;
unsigned char user_session_key[16]; unsigned char user_session_key[16];
@@ -985,19 +985,18 @@ static NTSTATUS _net_sam_logon_internal(pipes_struct *p,
DEBUG(1, ("_net_sam_logon: user %s\\%s has user sid " DEBUG(1, ("_net_sam_logon: user %s\\%s has user sid "
"%s\n but group sid %s.\n" "%s\n but group sid %s.\n"
"The conflicting domain portions are not " "The conflicting domain portions are not "
"supported for NETLOGON calls\n", "supported for NETLOGON calls\n",
pdb_get_domain(sampw), pdb_get_domain(sampw),
pdb_get_username(sampw), pdb_get_username(sampw),
sid_to_string(user_sid_string, user_sid), sid_to_string(user_sid_string, user_sid),
sid_to_string(group_sid_string, group_sid))); sid_to_string(group_sid_string, group_sid)));
return NT_STATUS_UNSUCCESSFUL; return NT_STATUS_UNSUCCESSFUL;
} }
if(server_info->login_server) { if(server_info->login_server) {
pstrcpy(my_name, server_info->login_server); my_name = server_info->login_server;
} else { } else {
pstrcpy(my_name, global_myname()); my_name = global_myname();
} }
status = nt_token_to_group_list(p->mem_ctx, &domain_sid, status = nt_token_to_group_list(p->mem_ctx, &domain_sid,
@@ -1011,7 +1010,7 @@ static NTSTATUS _net_sam_logon_internal(pipes_struct *p,
if (server_info->user_session_key.length) { if (server_info->user_session_key.length) {
memcpy(user_session_key, memcpy(user_session_key,
server_info->user_session_key.data, server_info->user_session_key.data,
MIN(sizeof(user_session_key), MIN(sizeof(user_session_key),
server_info->user_session_key.length)); server_info->user_session_key.length));
if (process_creds) { if (process_creds) {
@@ -1029,7 +1028,7 @@ static NTSTATUS _net_sam_logon_internal(pipes_struct *p,
} }
if (server_info->lm_session_key.length) { if (server_info->lm_session_key.length) {
memcpy(lm_session_key, memcpy(lm_session_key,
server_info->lm_session_key.data, server_info->lm_session_key.data,
MIN(sizeof(lm_session_key), MIN(sizeof(lm_session_key),
server_info->lm_session_key.length)); server_info->lm_session_key.length));
if (process_creds) { if (process_creds) {
@@ -1045,10 +1044,10 @@ static NTSTATUS _net_sam_logon_internal(pipes_struct *p,
SamOEMhash(lm_session_key, pipe_session_key, 16); SamOEMhash(lm_session_key, pipe_session_key, 16);
memset(pipe_session_key, '\0', 16); memset(pipe_session_key, '\0', 16);
} }
init_net_user_info3(p->mem_ctx, usr_info, init_net_user_info3(p->mem_ctx, usr_info,
user_rid, user_rid,
group_rid, group_rid,
pdb_get_username(sampw), pdb_get_username(sampw),
pdb_get_fullname(sampw), pdb_get_fullname(sampw),
pdb_get_homedir(sampw), pdb_get_homedir(sampw),
@@ -1071,7 +1070,7 @@ static NTSTATUS _net_sam_logon_internal(pipes_struct *p,
server_info->lm_session_key.length ? lm_session_key : NULL, server_info->lm_session_key.length ? lm_session_key : NULL,
my_name , /* char *logon_srv */ my_name , /* char *logon_srv */
pdb_get_domain(sampw), pdb_get_domain(sampw),
&domain_sid); /* DOM_SID *dom_sid */ &domain_sid); /* DOM_SID *dom_sid */
ZERO_STRUCT(user_session_key); ZERO_STRUCT(user_session_key);
ZERO_STRUCT(lm_session_key); ZERO_STRUCT(lm_session_key);
} }

View File

@@ -235,7 +235,8 @@ void copy_id21_to_sam_passwd(struct samu *to, SAM_USER_INFO_21 *from)
} }
if (from->fields_present & ACCT_LOGON_HOURS) { if (from->fields_present & ACCT_LOGON_HOURS) {
pstring oldstr, newstr; char oldstr[44]; /* hours strings are 42 bytes. */
char newstr[44];
DEBUG(15,("INFO_21 LOGON_DIVS: %08X -> %08X\n",pdb_get_logon_divs(to),from->logon_divs)); DEBUG(15,("INFO_21 LOGON_DIVS: %08X -> %08X\n",pdb_get_logon_divs(to),from->logon_divs));
if (from->logon_divs != pdb_get_logon_divs(to)) { if (from->logon_divs != pdb_get_logon_divs(to)) {
pdb_set_logon_divs(to, from->logon_divs, PDB_CHANGED); pdb_set_logon_divs(to, from->logon_divs, PDB_CHANGED);

View File

@@ -1472,7 +1472,7 @@ char *valid_share_pathname(TALLOC_CTX *ctx, const char *dos_pathname)
} }
/* Convert any '\' paths to '/' */ /* Convert any '\' paths to '/' */
unix_format(ptr); unix_format(ptr);
ptr = unix_clean_name(talloc_tos(), ptr); ptr = unix_clean_name(ctx, ptr);
if (!ptr) { if (!ptr) {
return NULL; return NULL;
} }

View File

@@ -288,29 +288,34 @@ WERROR _svcctl_open_service(pipes_struct *p, SVCCTL_Q_OPEN_SERVICE *q_u, SVCCTL_
SEC_DESC *sec_desc; SEC_DESC *sec_desc;
uint32 access_granted = 0; uint32 access_granted = 0;
NTSTATUS status; NTSTATUS status;
pstring service; char *service = NULL;
size_t ret = rpcstr_pull_talloc(p->mem_ctx,
&service,
q_u->servicename.buffer,
q_u->servicename.uni_str_len*2,
0);
rpcstr_pull(service, q_u->servicename.buffer, sizeof(service), q_u->servicename.uni_str_len*2, 0); if (ret == (size_t)-1 || !service) {
return WERR_NOMEM;
}
DEBUG(5, ("_svcctl_open_service: Attempting to open Service [%s], \n", service)); DEBUG(5, ("_svcctl_open_service: Attempting to open Service [%s], \n", service));
/* based on my tests you can open a service if you have a valid scm handle */ /* based on my tests you can open a service if you have a valid scm handle */
if ( !find_service_info_by_hnd( p, &q_u->handle ) ) if ( !find_service_info_by_hnd( p, &q_u->handle ) )
return WERR_BADFID; return WERR_BADFID;
/* perform access checks. Use the root token in order to ensure that we /* perform access checks. Use the root token in order to ensure that we
retrieve the security descriptor */ retrieve the security descriptor */
if ( !(sec_desc = svcctl_get_secdesc( p->mem_ctx, service, get_root_nt_token() )) ) if ( !(sec_desc = svcctl_get_secdesc( p->mem_ctx, service, get_root_nt_token() )) )
return WERR_NOMEM; return WERR_NOMEM;
se_map_generic( &q_u->access, &svc_generic_map ); se_map_generic( &q_u->access, &svc_generic_map );
status = svcctl_access_check( sec_desc, p->pipe_user.nt_user_token, q_u->access, &access_granted ); status = svcctl_access_check( sec_desc, p->pipe_user.nt_user_token, q_u->access, &access_granted );
if ( !NT_STATUS_IS_OK(status) ) if ( !NT_STATUS_IS_OK(status) )
return ntstatus_to_werror( status ); return ntstatus_to_werror( status );
return create_open_service_handle( p, &r_u->handle, SVC_HANDLE_IS_SERVICE, service, access_granted ); return create_open_service_handle( p, &r_u->handle, SVC_HANDLE_IS_SERVICE, service, access_granted );
} }

View File

@@ -494,21 +494,23 @@ WERROR _winreg_InitiateSystemShutdown(pipes_struct *p, struct winreg_InitiateSys
WERROR _winreg_InitiateSystemShutdownEx(pipes_struct *p, struct winreg_InitiateSystemShutdownEx *r) WERROR _winreg_InitiateSystemShutdownEx(pipes_struct *p, struct winreg_InitiateSystemShutdownEx *r)
{ {
pstring shutdown_script; char *shutdown_script = NULL;
char *msg = NULL; char *msg = NULL;
pstring chkmsg; char *chkmsg = NULL;
fstring str_timeout; fstring str_timeout;
fstring str_reason; fstring str_reason;
fstring reboot; fstring reboot;
fstring f; fstring f;
int ret; int ret;
bool can_shutdown; bool can_shutdown;
pstrcpy(shutdown_script, lp_shutdown_script()); shutdown_script = talloc_strdup(p->mem_ctx, lp_shutdown_script());
if (!shutdown_script) {
if ( !*shutdown_script ) return WERR_NOMEM;
}
if (!*shutdown_script) {
return WERR_ACCESS_DENIED; return WERR_ACCESS_DENIED;
}
/* pull the message string and perform necessary sanity checks on it */ /* pull the message string and perform necessary sanity checks on it */
@@ -518,66 +520,86 @@ WERROR _winreg_InitiateSystemShutdownEx(pipes_struct *p, struct winreg_InitiateS
if ( (msg = talloc_strdup(p->mem_ctx, r->in.message->name->name )) == NULL ) { if ( (msg = talloc_strdup(p->mem_ctx, r->in.message->name->name )) == NULL ) {
return WERR_NOMEM; return WERR_NOMEM;
} }
alpha_strcpy (chkmsg, msg, NULL, sizeof(chkmsg)); chkmsg = TALLOC_ARRAY(p->mem_ctx, char, strlen(msg)+1);
} if (!chkmsg) {
return WERR_NOMEM;
}
alpha_strcpy(chkmsg, msg, NULL, strlen(msg)+1);
}
fstr_sprintf(str_timeout, "%d", r->in.timeout); fstr_sprintf(str_timeout, "%d", r->in.timeout);
fstr_sprintf(reboot, r->in.reboot ? SHUTDOWN_R_STRING : ""); fstr_sprintf(reboot, r->in.reboot ? SHUTDOWN_R_STRING : "");
fstr_sprintf(f, r->in.force_apps ? SHUTDOWN_F_STRING : ""); fstr_sprintf(f, r->in.force_apps ? SHUTDOWN_F_STRING : "");
fstr_sprintf(str_reason, "%d", r->in.reason ); fstr_sprintf(str_reason, "%d", r->in.reason );
all_string_sub( shutdown_script, "%z", chkmsg, sizeof(shutdown_script) ); shutdown_script = talloc_all_string_sub(p->mem_ctx,
all_string_sub( shutdown_script, "%t", str_timeout, sizeof(shutdown_script) ); shutdown_script, "%z", chkmsg ? chkmsg : "");
all_string_sub( shutdown_script, "%r", reboot, sizeof(shutdown_script) ); if (!shutdown_script) {
all_string_sub( shutdown_script, "%f", f, sizeof(shutdown_script) ); return WERR_NOMEM;
all_string_sub( shutdown_script, "%x", str_reason, sizeof(shutdown_script) ); }
shutdown_script = talloc_all_string_sub(p->mem_ctx,
shutdown_script, "%t", str_timeout);
if (!shutdown_script) {
return WERR_NOMEM;
}
shutdown_script = talloc_all_string_sub(p->mem_ctx,
shutdown_script, "%r", reboot);
if (!shutdown_script) {
return WERR_NOMEM;
}
shutdown_script = talloc_all_string_sub(p->mem_ctx,
shutdown_script, "%f", f);
if (!shutdown_script) {
return WERR_NOMEM;
}
shutdown_script = talloc_all_string_sub(p->mem_ctx,
shutdown_script, "%x", str_reason);
if (!shutdown_script) {
return WERR_NOMEM;
}
can_shutdown = user_has_privileges( p->pipe_user.nt_user_token, &se_remote_shutdown ); can_shutdown = user_has_privileges( p->pipe_user.nt_user_token, &se_remote_shutdown );
/* IF someone has privs, run the shutdown script as root. OTHERWISE run it as not root /* IF someone has privs, run the shutdown script as root. OTHERWISE run it as not root
Take the error return from the script and provide it as the Windows return code. */ Take the error return from the script and provide it as the Windows return code. */
/********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/ /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
if ( can_shutdown ) if ( can_shutdown )
become_root(); become_root();
ret = smbrun( shutdown_script, NULL ); ret = smbrun( shutdown_script, NULL );
if ( can_shutdown ) if ( can_shutdown )
unbecome_root(); unbecome_root();
/********** END SeRemoteShutdownPrivilege BLOCK **********/ /********** END SeRemoteShutdownPrivilege BLOCK **********/
DEBUG(3,("_reg_shutdown_ex: Running the command `%s' gave %d\n", DEBUG(3,("_reg_shutdown_ex: Running the command `%s' gave %d\n",
shutdown_script, ret)); shutdown_script, ret));
return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED; return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
} }
/******************************************************************* /*******************************************************************
reg_abort_shutdwon reg_abort_shutdwon
********************************************************************/ ********************************************************************/
WERROR _winreg_AbortSystemShutdown(pipes_struct *p, struct winreg_AbortSystemShutdown *r) WERROR _winreg_AbortSystemShutdown(pipes_struct *p, struct winreg_AbortSystemShutdown *r)
{ {
pstring abort_shutdown_script; const char *abort_shutdown_script;
int ret; int ret;
bool can_shutdown; bool can_shutdown;
pstrcpy(abort_shutdown_script, lp_abort_shutdown_script()); abort_shutdown_script = lp_abort_shutdown_script();
if ( !*abort_shutdown_script ) if (!*abort_shutdown_script)
return WERR_ACCESS_DENIED; return WERR_ACCESS_DENIED;
can_shutdown = user_has_privileges( p->pipe_user.nt_user_token, &se_remote_shutdown ); can_shutdown = user_has_privileges( p->pipe_user.nt_user_token, &se_remote_shutdown );
/********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/ /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
if ( can_shutdown ) if ( can_shutdown )
become_root(); become_root();
@@ -597,49 +619,45 @@ WERROR _winreg_AbortSystemShutdown(pipes_struct *p, struct winreg_AbortSystemShu
/******************************************************************* /*******************************************************************
********************************************************************/ ********************************************************************/
static int validate_reg_filename( pstring fname ) static int validate_reg_filename(TALLOC_CTX *ctx, char **pp_fname )
{ {
char *p; char *p = NULL;
int num_services = lp_numservices(); int num_services = lp_numservices();
int snum; int snum = -1;
pstring share_path; const char *share_path;
pstring unix_fname; char *fname = *pp_fname;
/* convert to a unix path, stripping the C:\ along the way */ /* convert to a unix path, stripping the C:\ along the way */
if ( !(p = valid_share_pathname(NULL, fname))) if (!(p = valid_share_pathname(ctx, fname))) {
return -1; return -1;
}
/* has to exist within a valid file share */ /* has to exist within a valid file share */
for ( snum=0; snum<num_services; snum++ ) { for (snum=0; snum<num_services; snum++) {
if (!lp_snum_ok(snum) || lp_print_ok(snum)) {
if ( !lp_snum_ok(snum) || lp_print_ok(snum) )
continue; continue;
}
pstrcpy( share_path, lp_pathname(snum) ); share_path = lp_pathname(snum);
/* make sure we have a path (e.g. [homes] ) */ /* make sure we have a path (e.g. [homes] ) */
if (strlen(share_path) == 0) {
if ( strlen( share_path ) == 0 )
continue; continue;
}
if ( strncmp( share_path, p, strlen( share_path )) == 0 ) if (strncmp(share_path, p, strlen(share_path)) == 0) {
break; break;
}
} }
/* p and fname are overlapping memory so copy out and back in again */ *pp_fname = p;
pstrcpy( unix_fname, p );
pstrcpy( fname, unix_fname );
TALLOC_FREE(p);
return (snum < num_services) ? snum : -1; return (snum < num_services) ? snum : -1;
} }
/******************************************************************* /*******************************************************************
Note: topkeypat is the *full* path that this *key will be Note: topkeypat is the *full* path that this *key will be
loaded into (including the name of the key) loaded into (including the name of the key)
********************************************************************/ ********************************************************************/
@@ -651,11 +669,11 @@ static WERROR reg_load_tree( REGF_FILE *regfile, const char *topkeypath,
REGVAL_CTR *values; REGVAL_CTR *values;
REGSUBKEY_CTR *subkeys; REGSUBKEY_CTR *subkeys;
int i; int i;
pstring path; char *path = NULL;
WERROR result = WERR_OK; WERROR result = WERR_OK;
/* initialize the REGISTRY_KEY structure */ /* initialize the REGISTRY_KEY structure */
if ( !(registry_key.hook = reghook_cache_find(topkeypath)) ) { if ( !(registry_key.hook = reghook_cache_find(topkeypath)) ) {
DEBUG(0,("reg_load_tree: Failed to assigned a REGISTRY_HOOK to [%s]\n", DEBUG(0,("reg_load_tree: Failed to assigned a REGISTRY_HOOK to [%s]\n",
topkeypath )); topkeypath ));
@@ -667,48 +685,54 @@ static WERROR reg_load_tree( REGF_FILE *regfile, const char *topkeypath,
DEBUG(0,("reg_load_tree: Talloc failed for reg_key.name!\n")); DEBUG(0,("reg_load_tree: Talloc failed for reg_key.name!\n"));
return WERR_NOMEM; return WERR_NOMEM;
} }
/* now start parsing the values and subkeys */ /* now start parsing the values and subkeys */
if ( !(subkeys = TALLOC_ZERO_P( regfile->mem_ctx, REGSUBKEY_CTR )) ) if ( !(subkeys = TALLOC_ZERO_P( regfile->mem_ctx, REGSUBKEY_CTR )) )
return WERR_NOMEM; return WERR_NOMEM;
if ( !(values = TALLOC_ZERO_P( subkeys, REGVAL_CTR )) ) if ( !(values = TALLOC_ZERO_P( subkeys, REGVAL_CTR )) )
return WERR_NOMEM; return WERR_NOMEM;
/* copy values into the REGVAL_CTR */ /* copy values into the REGVAL_CTR */
for ( i=0; i<key->num_values; i++ ) { for ( i=0; i<key->num_values; i++ ) {
regval_ctr_addvalue( values, key->values[i].valuename, key->values[i].type, regval_ctr_addvalue( values, key->values[i].valuename, key->values[i].type,
(char*)key->values[i].data, (key->values[i].data_size & ~VK_DATA_IN_OFFSET) ); (char*)key->values[i].data, (key->values[i].data_size & ~VK_DATA_IN_OFFSET) );
} }
/* copy subkeys into the REGSUBKEY_CTR */ /* copy subkeys into the REGSUBKEY_CTR */
key->subkey_index = 0; key->subkey_index = 0;
while ( (subkey = regfio_fetch_subkey( regfile, key )) ) { while ( (subkey = regfio_fetch_subkey( regfile, key )) ) {
regsubkey_ctr_addkey( subkeys, subkey->keyname ); regsubkey_ctr_addkey( subkeys, subkey->keyname );
} }
/* write this key and values out */ /* write this key and values out */
if ( !store_reg_values( &registry_key, values ) if ( !store_reg_values( &registry_key, values )
|| !store_reg_keys( &registry_key, subkeys ) ) || !store_reg_keys( &registry_key, subkeys ) )
{ {
DEBUG(0,("reg_load_tree: Failed to load %s!\n", topkeypath)); DEBUG(0,("reg_load_tree: Failed to load %s!\n", topkeypath));
result = WERR_REG_IO_FAILURE; result = WERR_REG_IO_FAILURE;
} }
TALLOC_FREE( subkeys ); TALLOC_FREE( subkeys );
if ( !W_ERROR_IS_OK(result) ) if ( !W_ERROR_IS_OK(result) )
return result; return result;
/* now continue to load each subkey registry tree */ /* now continue to load each subkey registry tree */
key->subkey_index = 0; key->subkey_index = 0;
while ( (subkey = regfio_fetch_subkey( regfile, key )) ) { while ( (subkey = regfio_fetch_subkey( regfile, key )) ) {
pstr_sprintf( path, "%s%s%s", topkeypath, "\\", subkey->keyname ); path = talloc_asprintf(regfile->mem_ctx,
"%s\\%s",
topkeypath,
subkey->keyname);
if (!path) {
return WERR_NOMEM;
}
result = reg_load_tree( regfile, path, subkey ); result = reg_load_tree( regfile, path, subkey );
if ( !W_ERROR_IS_OK(result) ) if ( !W_ERROR_IS_OK(result) )
break; break;
@@ -741,13 +765,13 @@ static WERROR restore_registry_key ( REGISTRY_KEY *krecord, const char *fname )
regfio_close( regfile ); regfio_close( regfile );
return WERR_REG_FILE_INVALID; return WERR_REG_FILE_INVALID;
} }
result = reg_load_tree( regfile, krecord->name, rootkey ); result = reg_load_tree( regfile, krecord->name, rootkey );
/* cleanup */ /* cleanup */
regfio_close( regfile ); regfio_close( regfile );
return result; return result;
} }
@@ -757,28 +781,31 @@ static WERROR restore_registry_key ( REGISTRY_KEY *krecord, const char *fname )
WERROR _winreg_RestoreKey(pipes_struct *p, struct winreg_RestoreKey *r) WERROR _winreg_RestoreKey(pipes_struct *p, struct winreg_RestoreKey *r)
{ {
struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle ); struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
pstring fname; char *fname = NULL;
int snum; int snum;
if ( !regkey ) if ( !regkey )
return WERR_BADFID; return WERR_BADFID;
if ( !r->in.filename || !r->in.filename->name ) if ( !r->in.filename || !r->in.filename->name )
return WERR_INVALID_PARAM; return WERR_INVALID_PARAM;
pstrcpy( fname, r->in.filename->name ); fname - talloc_strdup(p->mem_ctx, r->in.filename->name);
if (!fname) {
return WERR_NOMEM;
}
DEBUG(8,("_winreg_RestoreKey: verifying restore of key [%s] from " DEBUG(8,("_winreg_RestoreKey: verifying restore of key [%s] from "
"\"%s\"\n", regkey->key->name, fname)); "\"%s\"\n", regkey->key->name, fname));
if ( (snum = validate_reg_filename( fname )) == -1 ) if ((snum = validate_reg_filename(p->mem_ctx, &fname)) == -1)
return WERR_OBJECT_PATH_INVALID; return WERR_OBJECT_PATH_INVALID;
/* user must posses SeRestorePrivilege for this this proceed */ /* user must posses SeRestorePrivilege for this this proceed */
if ( !user_has_privileges( p->pipe_user.nt_user_token, &se_restore ) ) if ( !user_has_privileges( p->pipe_user.nt_user_token, &se_restore ) )
return WERR_ACCESS_DENIED; return WERR_ACCESS_DENIED;
DEBUG(2,("_winreg_RestoreKey: Restoring [%s] from %s in share %s\n", DEBUG(2,("_winreg_RestoreKey: Restoring [%s] from %s in share %s\n",
regkey->key->name, fname, lp_servicename(snum) )); regkey->key->name, fname, lp_servicename(snum) ));
@@ -795,30 +822,33 @@ static WERROR reg_write_tree( REGF_FILE *regfile, const char *keypath,
REGVAL_CTR *values; REGVAL_CTR *values;
REGSUBKEY_CTR *subkeys; REGSUBKEY_CTR *subkeys;
int i, num_subkeys; int i, num_subkeys;
pstring key_tmp; char *key_tmp = NULL;
char *keyname, *parentpath; char *keyname, *parentpath;
pstring subkeypath; char *subkeypath = NULL;
char *subkeyname; char *subkeyname;
REGISTRY_KEY registry_key; REGISTRY_KEY registry_key;
WERROR result = WERR_OK; WERROR result = WERR_OK;
if ( !regfile ) if (!regfile)
return WERR_GENERAL_FAILURE; return WERR_GENERAL_FAILURE;
if ( !keypath ) if (!keypath)
return WERR_OBJECT_PATH_INVALID; return WERR_OBJECT_PATH_INVALID;
/* split up the registry key path */ /* split up the registry key path */
pstrcpy( key_tmp, keypath ); key_tmp = talloc_strdup(regfile->mem_ctx, keypath);
if ( !reg_split_key( key_tmp, &parentpath, &keyname ) ) if (!key_tmp) {
return WERR_NOMEM;
}
if (!reg_split_key( key_tmp, &parentpath, &keyname ) )
return WERR_OBJECT_PATH_INVALID; return WERR_OBJECT_PATH_INVALID;
if ( !keyname ) if ( !keyname )
keyname = parentpath; keyname = parentpath;
/* we need a REGISTRY_KEY object here to enumerate subkeys and values */ /* we need a REGISTRY_KEY object here to enumerate subkeys and values */
ZERO_STRUCT( registry_key ); ZERO_STRUCT( registry_key );
if ( (registry_key.name = talloc_strdup(regfile->mem_ctx, keypath)) == NULL ) if ( (registry_key.name = talloc_strdup(regfile->mem_ctx, keypath)) == NULL )
@@ -828,8 +858,8 @@ static WERROR reg_write_tree( REGF_FILE *regfile, const char *keypath,
return WERR_BADFILE; return WERR_BADFILE;
/* lookup the values and subkeys */ /* lookup the values and subkeys */
if ( !(subkeys = TALLOC_ZERO_P( regfile->mem_ctx, REGSUBKEY_CTR )) ) if ( !(subkeys = TALLOC_ZERO_P( regfile->mem_ctx, REGSUBKEY_CTR )) )
return WERR_NOMEM; return WERR_NOMEM;
if ( !(values = TALLOC_ZERO_P( subkeys, REGVAL_CTR )) ) if ( !(values = TALLOC_ZERO_P( subkeys, REGVAL_CTR )) )
@@ -839,7 +869,7 @@ static WERROR reg_write_tree( REGF_FILE *regfile, const char *keypath,
fetch_reg_values( &registry_key, values ); fetch_reg_values( &registry_key, values );
/* write out this key */ /* write out this key */
if ( !(key = regfio_write_key( regfile, keyname, values, subkeys, sec_desc, parent )) ) { if ( !(key = regfio_write_key( regfile, keyname, values, subkeys, sec_desc, parent )) ) {
result = WERR_CAN_NOT_COMPLETE; result = WERR_CAN_NOT_COMPLETE;
goto done; goto done;
@@ -850,7 +880,12 @@ static WERROR reg_write_tree( REGF_FILE *regfile, const char *keypath,
num_subkeys = regsubkey_ctr_numkeys( subkeys ); num_subkeys = regsubkey_ctr_numkeys( subkeys );
for ( i=0; i<num_subkeys; i++ ) { for ( i=0; i<num_subkeys; i++ ) {
subkeyname = regsubkey_ctr_specific_key( subkeys, i ); subkeyname = regsubkey_ctr_specific_key( subkeys, i );
pstr_sprintf( subkeypath, "%s\\%s", keypath, subkeyname ); subkeypath = talloc_asprintf(regfile->mem_ctx,
"%s\\%s", keypath, subkeyname);
if (!subkeypath) {
result = WERR_NOMEM;
goto done;
}
result = reg_write_tree( regfile, subkeypath, key, sec_desc ); result = reg_write_tree( regfile, subkeypath, key, sec_desc );
if ( !W_ERROR_IS_OK(result) ) if ( !W_ERROR_IS_OK(result) )
goto done; goto done;
@@ -915,26 +950,26 @@ static WERROR backup_registry_key ( REGISTRY_KEY *krecord, const char *fname )
SEC_DESC *sd = NULL; SEC_DESC *sd = NULL;
/* open the registry file....fail if the file already exists */ /* open the registry file....fail if the file already exists */
if ( !(regfile = regfio_open( fname, (O_RDWR|O_CREAT|O_EXCL), (S_IREAD|S_IWRITE) )) ) { if ( !(regfile = regfio_open( fname, (O_RDWR|O_CREAT|O_EXCL), (S_IREAD|S_IWRITE) )) ) {
DEBUG(0,("backup_registry_key: failed to open \"%s\" (%s)\n", DEBUG(0,("backup_registry_key: failed to open \"%s\" (%s)\n",
fname, strerror(errno) )); fname, strerror(errno) ));
return ( ntstatus_to_werror(map_nt_error_from_unix( errno )) ); return ( ntstatus_to_werror(map_nt_error_from_unix( errno )) );
} }
if ( !W_ERROR_IS_OK(result = make_default_reg_sd( regfile->mem_ctx, &sd )) ) { if ( !W_ERROR_IS_OK(result = make_default_reg_sd( regfile->mem_ctx, &sd )) ) {
regfio_close( regfile ); regfio_close( regfile );
return result; return result;
} }
/* write the registry tree to the file */ /* write the registry tree to the file */
result = reg_write_tree( regfile, krecord->name, NULL, sd ); result = reg_write_tree( regfile, krecord->name, NULL, sd );
/* cleanup */ /* cleanup */
regfio_close( regfile ); regfio_close( regfile );
return result; return result;
} }
@@ -944,26 +979,29 @@ static WERROR backup_registry_key ( REGISTRY_KEY *krecord, const char *fname )
WERROR _winreg_SaveKey(pipes_struct *p, struct winreg_SaveKey *r) WERROR _winreg_SaveKey(pipes_struct *p, struct winreg_SaveKey *r)
{ {
struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle ); struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
pstring fname; char *fname = NULL;
int snum; int snum = -1;
if ( !regkey ) if ( !regkey )
return WERR_BADFID; return WERR_BADFID;
if ( !r->in.filename || !r->in.filename->name ) if ( !r->in.filename || !r->in.filename->name )
return WERR_INVALID_PARAM; return WERR_INVALID_PARAM;
pstrcpy( fname, r->in.filename->name ); fname = talloc_strdup(p->mem_ctx, r->in.filename->name);
if (!fname) {
return WERR_NOMEM;
}
DEBUG(8,("_winreg_SaveKey: verifying backup of key [%s] to \"%s\"\n", DEBUG(8,("_winreg_SaveKey: verifying backup of key [%s] to \"%s\"\n",
regkey->key->name, fname)); regkey->key->name, fname));
if ( (snum = validate_reg_filename( fname )) == -1 ) if ((snum = validate_reg_filename(p->mem_ctx, &fname)) == -1 )
return WERR_OBJECT_PATH_INVALID; return WERR_OBJECT_PATH_INVALID;
DEBUG(2,("_winreg_SaveKey: Saving [%s] to %s in share %s\n", DEBUG(2,("_winreg_SaveKey: Saving [%s] to %s in share %s\n",
regkey->key->name, fname, lp_servicename(snum) )); regkey->key->name, fname, lp_servicename(snum) ));
return backup_registry_key( regkey->key, fname ); return backup_registry_key( regkey->key, fname );
} }