From 55b4f9d003b036af69085f7b64e0df08c5ba440d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 27 Nov 2007 11:22:58 -0800 Subject: [PATCH] Remove pstring from everything in rpc_server except srv_spoolss_nt.c and srv_srvsvc_nt.c. They're next :-). Jeremy. --- source/include/rpc_eventlog.h | 10 +- source/rpc_server/srv_eventlog_lib.c | 151 ++++++++++----------- source/rpc_server/srv_eventlog_nt.c | 162 ++++++++++++++-------- source/rpc_server/srv_netlog_nt.c | 27 ++-- source/rpc_server/srv_samr_util.c | 3 +- source/rpc_server/srv_srvsvc_nt.c | 2 +- source/rpc_server/srv_svcctl_nt.c | 25 ++-- source/rpc_server/srv_winreg_nt.c | 256 ++++++++++++++++++++--------------- 8 files changed, 363 insertions(+), 273 deletions(-) diff --git a/source/include/rpc_eventlog.h b/source/include/rpc_eventlog.h index 849c62b7b0f..9ec76a071c9 100644 --- a/source/include/rpc_eventlog.h +++ b/source/include/rpc_eventlog.h @@ -134,15 +134,15 @@ typedef struct { typedef struct { uint32 source_name_len; - wpstring source_name; + smb_ucs2_t *source_name; uint32 computer_name_len; - wpstring computer_name; + smb_ucs2_t *computer_name; uint32 sid_padding; - wpstring sid; + smb_ucs2_t *sid; uint32 strings_len; - wpstring strings; + smb_ucs2_t *strings; uint32 user_data_len; - pstring user_data; + char *user_data; uint32 data_padding; } Eventlog_data_record; diff --git a/source/rpc_server/srv_eventlog_lib.c b/source/rpc_server/srv_eventlog_lib.c index 00afe5b05c3..b9648283e1a 100644 --- a/source/rpc_server/srv_eventlog_lib.c +++ b/source/rpc_server/srv_eventlog_lib.c @@ -62,17 +62,16 @@ TDB_CONTEXT *elog_init_tdb( char *tdbfilename ) and size. Caller must free memory. ********************************************************************/ -char *elog_tdbname( const char *name ) +char *elog_tdbname(TALLOC_CTX *ctx, const char *name ) { - fstring path; - char *tdb_fullpath; - char *eventlogdir = state_path( "eventlog" ); - - pstr_sprintf( path, "%s/%s.tdb", eventlogdir, name ); - strlower_m( path ); - tdb_fullpath = SMB_STRDUP( path ); - - return tdb_fullpath; + char *path = talloc_asprintf(ctx, "%s/%s.tdb", + state_path("eventlog"), + name); + if (!path) { + return NULL; + } + strlower_m(path); + return path; } @@ -320,13 +319,13 @@ ELOG_TDB *elog_open_tdb( char *logname, bool force_clear ) TDB_CONTEXT *tdb = NULL; uint32 vers_id; ELOG_TDB *ptr; - char *tdbfilename; - pstring tdbpath; + char *tdbpath = NULL; ELOG_TDB *tdb_node = NULL; char *eventlogdir; + TALLOC_CTX *ctx = talloc_tos(); /* first see if we have an open context */ - + for ( ptr=open_elog_list; ptr; ptr=ptr->next ) { if ( strequal( ptr->name, logname ) ) { ptr->ref_count++; @@ -345,27 +344,28 @@ ELOG_TDB *elog_open_tdb( char *logname, bool force_clear ) return ptr; } } - + /* make sure that the eventlog dir exists */ - + eventlogdir = state_path( "eventlog" ); 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", + 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" )); - + /* the tdb wasn't already open or this is a forced clear open */ 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 ) { 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 ) { + TALLOC_CTX *ctx = talloc_tos(); char *start = NULL, *stop = NULL; - pstring temp; - int temp_len = 0; start = line; @@ -661,62 +660,69 @@ bool parse_logentry( char *line, Eventlog_entry * entry, bool * eor ) } else if ( 0 == strncmp( start, "USL", stop - start ) ) { entry->record.user_sid_length = atoi( stop + 1 ); } else if ( 0 == strncmp( start, "SRC", stop - start ) ) { - memset( temp, 0, sizeof( temp ) ); stop++; while ( isspace( stop[0] ) ) { stop++; } - temp_len = strlen( stop ); - strncpy( temp, stop, temp_len ); - rpcstr_push( ( void * ) ( entry->data_record.source_name ), - temp, sizeof( entry->data_record.source_name ), - STR_TERMINATE ); - entry->data_record.source_name_len = - ( strlen_w( entry->data_record.source_name ) * 2 ) + - 2; + entry->data_record.source_name_len = rpcstr_push_talloc(ctx, + &entry->data_record.source_name, + stop); + if (entry->data_record.source_name_len == (size_t)-1 || + entry->data_record.source_name == NULL) { + return false; + } } else if ( 0 == strncmp( start, "SRN", stop - start ) ) { - memset( temp, 0, sizeof( temp ) ); stop++; while ( isspace( stop[0] ) ) { stop++; } - temp_len = strlen( stop ); - strncpy( temp, stop, temp_len ); - rpcstr_push( ( void * ) ( entry->data_record.computer_name ), - temp, sizeof( entry->data_record.computer_name ), - STR_TERMINATE ); - entry->data_record.computer_name_len = - ( strlen_w( entry->data_record.computer_name ) * 2 ) + - 2; + entry->data_record.computer_name_len = rpcstr_push_talloc(ctx, + &entry->data_record.computer_name, + stop); + if (entry->data_record.computer_name_len == (size_t)-1 || + entry->data_record.computer_name == NULL) { + return false; + } } else if ( 0 == strncmp( start, "SID", stop - start ) ) { - memset( temp, 0, sizeof( temp ) ); stop++; while ( isspace( stop[0] ) ) { stop++; } - temp_len = strlen( stop ); - strncpy( temp, stop, temp_len ); - rpcstr_push( ( void * ) ( entry->data_record.sid ), temp, - sizeof( entry->data_record.sid ), - STR_TERMINATE ); - entry->record.user_sid_length = - ( strlen_w( entry->data_record.sid ) * 2 ) + 2; + entry->record.user_sid_length = rpcstr_push_talloc(ctx, + &entry->data_record.sid, + stop); + if (entry->record.user_sid_length == (size_t)-1 || + entry->data_record.sid == NULL) { + return false; + } } else if ( 0 == strncmp( start, "STR", stop - start ) ) { + smb_ucs2_t *temp = NULL; + size_t tmp_len; + uint32_t old_len; /* skip past initial ":" */ stop++; /* now skip any other leading whitespace */ - while ( isspace( stop[0] ) ) { + while ( isspace(stop[0])) { stop++; } - temp_len = strlen( stop ); - memset( temp, 0, sizeof( temp ) ); - strncpy( temp, stop, temp_len ); - rpcstr_push( ( void * ) ( entry->data_record.strings + - ( entry->data_record.strings_len / 2 ) ), - temp, - sizeof( entry->data_record.strings ) - - ( entry->data_record.strings_len / 2 ), STR_TERMINATE ); - entry->data_record.strings_len += ( temp_len * 2 ) + 2; + tmp_len = rpcstr_push_talloc(ctx, + &temp, + stop); + if (tmp_len == (size_t)-1 || !temp) { + return false; + } + old_len = entry->data_record.strings_len; + entry->data_record.strings = (smb_ucs2_t *)TALLOC_REALLOC_ARRAY(ctx, + 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++; } else if ( 0 == strncmp( start, "DAT", stop - start ) ) { /* skip past initial ":" */ @@ -725,25 +731,18 @@ bool parse_logentry( char *line, Eventlog_entry * entry, bool * eor ) while ( isspace( stop[0] ) ) { stop++; } - entry->data_record.user_data_len = strlen( stop ); - memset( entry->data_record.user_data, 0, - sizeof( entry->data_record.user_data ) ); - if ( entry->data_record.user_data_len > 0 ) { - /* copy no more than the first 1024 bytes */ - 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 ); + entry->data_record.user_data_len = strlen(stop); + entry->data_record.user_data = talloc_strdup(ctx, + stop); + if (!entry->data_record.user_data) { + return false; } } else { /* some other eventlog entry -- not implemented, so dropping on the floor */ DEBUG( 10, ( "Unknown entry [%s]. Ignoring.\n", line ) ); /* For now return true so that we can keep on parsing this mess. Eventually we will return False here. */ - return True; + return true; } - return True; + return true; } diff --git a/source/rpc_server/srv_eventlog_nt.c b/source/rpc_server/srv_eventlog_nt.c index d86da9054cb..cd06be1984c 100644 --- a/source/rpc_server/srv_eventlog_nt.c +++ b/source/rpc_server/srv_eventlog_nt.c @@ -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 ) { - char *tdbname = elog_tdbname( info->logname ); + char *tdbname = elog_tdbname(talloc_tos(), info->logname ); SEC_DESC *sec_desc; bool ret; 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. ********************************************************************/ -static Eventlog_entry *get_eventlog_record( prs_struct * ps, TDB_CONTEXT * tdb, - int recno, Eventlog_entry * ee ) +static Eventlog_entry *get_eventlog_record(prs_struct *ps, + TDB_CONTEXT *tdb, + int recno) { + Eventlog_entry *ee = NULL; TDB_DATA ret, key; int srecno; int reclen; 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; key.dptr = ( uint8 * ) &srecno; @@ -316,10 +322,11 @@ static Eventlog_entry *get_eventlog_record( prs_struct * ps, TDB_CONTEXT * tdb, if ( !len ) return NULL; - /* ee = PRS_ALLOC_MEM(ps, Eventlog_entry, 1); */ - - if ( !ee ) + ee = TALLOC_ARRAY(ps->mem_ctx, Eventlog_entry, 1); + if (!ee) { return NULL; + } + ZERO_STRUCTP(ee); len = tdb_unpack( ret.dptr, ret.dsize, "ddddddwwwwddddddBBdBBBd", &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 into it's 2nd argment for 'B' */ - if ( wpcomputer ) - memcpy( ee->data_record.computer_name, wpcomputer, - ee->data_record.computer_name_len ); - if ( wpsource ) - memcpy( ee->data_record.source_name, wpsource, - ee->data_record.source_name_len ); - - if ( wpsid ) - memcpy( ee->data_record.sid, wpsid, - ee->record.user_sid_length ); - if ( wpstrs ) - memcpy( ee->data_record.strings, wpstrs, - ee->data_record.strings_len ); - - /* note that userdata is a pstring */ - if ( puserdata ) - memcpy( ee->data_record.user_data, puserdata, - ee->data_record.user_data_len ); - - SAFE_FREE( wpcomputer ); - SAFE_FREE( wpsource ); - SAFE_FREE( wpsid ); - SAFE_FREE( wpstrs ); - SAFE_FREE( puserdata ); + if (wpcomputer) { + ee->data_record.computer_name = TALLOC_MEMDUP(ee, + wpcomputer, + ee->data_record.computer_name_len); + if (!ee->data_record.computer_name) { + 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) { + ee->data_record.sid = TALLOC_MEMDUP(ee, + wpsid, + ee->record.user_sid_length); + if (!ee->data_record.sid) { + 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; + } + } + + if (puserdata) { + ee->data_record.user_data = TALLOC_MEMDUP(ee, + puserdata, + ee->data_record.user_data_len); + if (!ee->data_record.user_data) { + TALLOC_FREE(ee); + goto out; + } + } + + out: + + SAFE_FREE(wpcomputer); + SAFE_FREE(wpsource); + SAFE_FREE(wpsid); + SAFE_FREE(wpstrs); + SAFE_FREE(puserdata); DEBUG( 10, ( "get_eventlog_record: read back %d\n", len ) ); DEBUG( 10, ( "get_eventlog_record: computer_name %d is ", ee->data_record.computer_name_len ) ); - SAFE_FREE( ret.dptr ); + SAFE_FREE(ret.dptr); 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 ) { - pstring path; + char *path = NULL; uint32 uiMaxSize; uint32 uiRetention; REGISTRY_KEY *keyinfo; @@ -395,6 +433,7 @@ static bool sync_eventlog_params( EVENTLOG_INFO *info ) REGVAL_CTR *values; WERROR wresult; char *elogname = info->logname; + TALLOC_CTX *ctx = talloc_tos(); 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 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, 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_INFO *info = find_eventlog_info_by_hnd( p, &q_u->handle ); - pstring backup_file_name; + char *backup_file_name = NULL; if ( !info ) return NT_STATUS_INVALID_HANDLE; - pstrcpy( backup_file_name, "" ); - if ( q_u->backupfile.string ) { - rpcstr_pull( backup_file_name, q_u->backupfile.string->buffer, - sizeof( backup_file_name ), - q_u->backupfile.string->uni_str_len * 2, 0 ); + if (q_u->backupfile.string) { + size_t len = rpcstr_pull_talloc(p->mem_ctx, + &backup_file_name, + q_u->backupfile.string->buffer, + 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 " "file name for log [%s].", @@ -647,7 +693,7 @@ NTSTATUS _eventlog_clear_eventlog( pipes_struct * p, /* Force a close and reopen */ - elog_close_tdb( info->etdb, True ); + elog_close_tdb( info->etdb, True ); become_root(); info->etdb = elog_open_tdb( info->logname, True ); unbecome_root(); @@ -674,7 +720,7 @@ NTSTATUS _eventlog_read_eventlog( pipes_struct * p, EVENTLOG_R_READ_EVENTLOG * r_u ) { 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; prs_struct *ps; int bytes_left, record_number; @@ -689,9 +735,9 @@ NTSTATUS _eventlog_read_eventlog( pipes_struct * p, bytes_left = q_u->max_read_size; - if ( !info->etdb ) + if ( !info->etdb ) return NT_STATUS_ACCESS_DENIED; - + /* 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); @@ -708,37 +754,39 @@ NTSTATUS _eventlog_read_eventlog( pipes_struct * p, if ( elog_read_type & EVENTLOG_SEQUENTIAL_READ ) record_number = info->current_record; - else + else record_number = q_u->offset; while ( bytes_left > 0 ) { /* 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; + } DEBUG( 8, ( "Retrieved record %d\n", record_number ) ); - + /* 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; 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; /* response would be too big to fit in client-size buffer */ - + bytes_left = 0; break; } - + add_record_to_resp( r_u, ee_new ); bytes_left -= ee_new->record.length; - ZERO_STRUCT( entry ); + TALLOC_FREE(entry); num_records_read = r_u->num_records - num_records_read; - + DEBUG( 10, ( "_eventlog_read_eventlog: read [%d] records for a total " "of [%d] records using [%d] bytes out of a max of [%d].\n", num_records_read, r_u->num_records, @@ -749,13 +797,13 @@ NTSTATUS _eventlog_read_eventlog( pipes_struct * p, record_number++; else record_number--; - + /* update the eventlog record pointer */ - + 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 */ return (num_records_read ? NT_STATUS_OK : NT_STATUS_BUFFER_TOO_SMALL); diff --git a/source/rpc_server/srv_netlog_nt.c b/source/rpc_server/srv_netlog_nt.c index b6ae104d1c9..29c60e07b5a 100644 --- a/source/rpc_server/srv_netlog_nt.c +++ b/source/rpc_server/srv_netlog_nt.c @@ -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 the SAM Local Security Authority should record that the user is logged in to the domain. */ - + { DOM_GID *gids = NULL; const DOM_SID *user_sid = NULL; const DOM_SID *group_sid = NULL; DOM_SID domain_sid; - uint32 user_rid, group_rid; + uint32 user_rid, group_rid; int num_gids = 0; - pstring my_name; + const char *my_name; fstring user_sid_string; fstring group_sid_string; 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 " "%s\n but group sid %s.\n" "The conflicting domain portions are not " - "supported for NETLOGON calls\n", + "supported for NETLOGON calls\n", pdb_get_domain(sampw), pdb_get_username(sampw), sid_to_string(user_sid_string, user_sid), sid_to_string(group_sid_string, group_sid))); return NT_STATUS_UNSUCCESSFUL; } - - + if(server_info->login_server) { - pstrcpy(my_name, server_info->login_server); + my_name = server_info->login_server; } else { - pstrcpy(my_name, global_myname()); + my_name = global_myname(); } 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) { memcpy(user_session_key, - server_info->user_session_key.data, + server_info->user_session_key.data, MIN(sizeof(user_session_key), server_info->user_session_key.length)); if (process_creds) { @@ -1029,7 +1028,7 @@ static NTSTATUS _net_sam_logon_internal(pipes_struct *p, } if (server_info->lm_session_key.length) { memcpy(lm_session_key, - server_info->lm_session_key.data, + server_info->lm_session_key.data, MIN(sizeof(lm_session_key), server_info->lm_session_key.length)); if (process_creds) { @@ -1045,10 +1044,10 @@ static NTSTATUS _net_sam_logon_internal(pipes_struct *p, SamOEMhash(lm_session_key, pipe_session_key, 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, - group_rid, + group_rid, pdb_get_username(sampw), pdb_get_fullname(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, my_name , /* char *logon_srv */ pdb_get_domain(sampw), - &domain_sid); /* DOM_SID *dom_sid */ + &domain_sid); /* DOM_SID *dom_sid */ ZERO_STRUCT(user_session_key); ZERO_STRUCT(lm_session_key); } diff --git a/source/rpc_server/srv_samr_util.c b/source/rpc_server/srv_samr_util.c index f7e20797a7e..bde79363433 100644 --- a/source/rpc_server/srv_samr_util.c +++ b/source/rpc_server/srv_samr_util.c @@ -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) { - 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)); if (from->logon_divs != pdb_get_logon_divs(to)) { pdb_set_logon_divs(to, from->logon_divs, PDB_CHANGED); diff --git a/source/rpc_server/srv_srvsvc_nt.c b/source/rpc_server/srv_srvsvc_nt.c index 51dffb89046..9788eb5bcc5 100644 --- a/source/rpc_server/srv_srvsvc_nt.c +++ b/source/rpc_server/srv_srvsvc_nt.c @@ -1472,7 +1472,7 @@ char *valid_share_pathname(TALLOC_CTX *ctx, const char *dos_pathname) } /* Convert any '\' paths to '/' */ unix_format(ptr); - ptr = unix_clean_name(talloc_tos(), ptr); + ptr = unix_clean_name(ctx, ptr); if (!ptr) { return NULL; } diff --git a/source/rpc_server/srv_svcctl_nt.c b/source/rpc_server/srv_svcctl_nt.c index a6a9c855aad..7d81033264a 100644 --- a/source/rpc_server/srv_svcctl_nt.c +++ b/source/rpc_server/srv_svcctl_nt.c @@ -288,29 +288,34 @@ WERROR _svcctl_open_service(pipes_struct *p, SVCCTL_Q_OPEN_SERVICE *q_u, SVCCTL_ SEC_DESC *sec_desc; uint32 access_granted = 0; NTSTATUS status; - pstring service; - - rpcstr_pull(service, q_u->servicename.buffer, sizeof(service), q_u->servicename.uni_str_len*2, 0); - + 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); + + if (ret == (size_t)-1 || !service) { + return WERR_NOMEM; + } 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 */ - + if ( !find_service_info_by_hnd( p, &q_u->handle ) ) return WERR_BADFID; - + /* perform access checks. Use the root token in order to ensure that we retrieve the security descriptor */ - + if ( !(sec_desc = svcctl_get_secdesc( p->mem_ctx, service, get_root_nt_token() )) ) return WERR_NOMEM; - + 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 ); if ( !NT_STATUS_IS_OK(status) ) return ntstatus_to_werror( status ); - + return create_open_service_handle( p, &r_u->handle, SVC_HANDLE_IS_SERVICE, service, access_granted ); } diff --git a/source/rpc_server/srv_winreg_nt.c b/source/rpc_server/srv_winreg_nt.c index 4b268dda19f..631386c078f 100644 --- a/source/rpc_server/srv_winreg_nt.c +++ b/source/rpc_server/srv_winreg_nt.c @@ -494,21 +494,23 @@ WERROR _winreg_InitiateSystemShutdown(pipes_struct *p, struct winreg_InitiateSys WERROR _winreg_InitiateSystemShutdownEx(pipes_struct *p, struct winreg_InitiateSystemShutdownEx *r) { - pstring shutdown_script; + char *shutdown_script = NULL; char *msg = NULL; - pstring chkmsg; + char *chkmsg = NULL; fstring str_timeout; fstring str_reason; fstring reboot; fstring f; int ret; bool can_shutdown; - - pstrcpy(shutdown_script, lp_shutdown_script()); - - if ( !*shutdown_script ) + shutdown_script = talloc_strdup(p->mem_ctx, lp_shutdown_script()); + if (!shutdown_script) { + return WERR_NOMEM; + } + if (!*shutdown_script) { return WERR_ACCESS_DENIED; + } /* 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 ) { 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(reboot, r->in.reboot ? SHUTDOWN_R_STRING : ""); fstr_sprintf(f, r->in.force_apps ? SHUTDOWN_F_STRING : ""); fstr_sprintf(str_reason, "%d", r->in.reason ); - all_string_sub( shutdown_script, "%z", chkmsg, sizeof(shutdown_script) ); - all_string_sub( shutdown_script, "%t", str_timeout, sizeof(shutdown_script) ); - all_string_sub( shutdown_script, "%r", reboot, sizeof(shutdown_script) ); - all_string_sub( shutdown_script, "%f", f, sizeof(shutdown_script) ); - all_string_sub( shutdown_script, "%x", str_reason, sizeof(shutdown_script) ); + shutdown_script = talloc_all_string_sub(p->mem_ctx, + shutdown_script, "%z", chkmsg ? chkmsg : ""); + if (!shutdown_script) { + return WERR_NOMEM; + } + 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 ); - + /* 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. */ - + /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/ - - if ( can_shutdown ) + + if ( can_shutdown ) become_root(); ret = smbrun( shutdown_script, NULL ); - + if ( can_shutdown ) unbecome_root(); /********** END SeRemoteShutdownPrivilege BLOCK **********/ - + DEBUG(3,("_reg_shutdown_ex: Running the command `%s' gave %d\n", shutdown_script, ret)); - return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED; } - - - /******************************************************************* reg_abort_shutdwon ********************************************************************/ WERROR _winreg_AbortSystemShutdown(pipes_struct *p, struct winreg_AbortSystemShutdown *r) { - pstring abort_shutdown_script; + const char *abort_shutdown_script; int ret; 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; - + can_shutdown = user_has_privileges( p->pipe_user.nt_user_token, &se_remote_shutdown ); - + /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/ - + if ( can_shutdown ) 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 snum; - pstring share_path; - pstring unix_fname; + int snum = -1; + const char *share_path; + char *fname = *pp_fname; /* 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; + } /* has to exist within a valid file share */ - for ( snum=0; snummem_ctx, REGSUBKEY_CTR )) ) return WERR_NOMEM; - + if ( !(values = TALLOC_ZERO_P( subkeys, REGVAL_CTR )) ) return WERR_NOMEM; /* copy values into the REGVAL_CTR */ - + for ( i=0; inum_values; i++ ) { 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) ); } /* copy subkeys into the REGSUBKEY_CTR */ - + key->subkey_index = 0; while ( (subkey = regfio_fetch_subkey( regfile, key )) ) { regsubkey_ctr_addkey( subkeys, subkey->keyname ); } - + /* write this key and values out */ - - if ( !store_reg_values( ®istry_key, values ) + + if ( !store_reg_values( ®istry_key, values ) || !store_reg_keys( ®istry_key, subkeys ) ) { DEBUG(0,("reg_load_tree: Failed to load %s!\n", topkeypath)); result = WERR_REG_IO_FAILURE; } - + TALLOC_FREE( subkeys ); - + if ( !W_ERROR_IS_OK(result) ) return result; - + /* now continue to load each subkey registry tree */ key->subkey_index = 0; 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 ); if ( !W_ERROR_IS_OK(result) ) break; @@ -741,13 +765,13 @@ static WERROR restore_registry_key ( REGISTRY_KEY *krecord, const char *fname ) regfio_close( regfile ); return WERR_REG_FILE_INVALID; } - + result = reg_load_tree( regfile, krecord->name, rootkey ); - + /* cleanup */ - + regfio_close( regfile ); - + 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) { struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle ); - pstring fname; + char *fname = NULL; int snum; - + if ( !regkey ) - return WERR_BADFID; + return WERR_BADFID; if ( !r->in.filename || !r->in.filename->name ) 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 " "\"%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; - + /* user must posses SeRestorePrivilege for this this proceed */ - + if ( !user_has_privileges( p->pipe_user.nt_user_token, &se_restore ) ) return WERR_ACCESS_DENIED; - + DEBUG(2,("_winreg_RestoreKey: Restoring [%s] from %s in share %s\n", 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; REGSUBKEY_CTR *subkeys; int i, num_subkeys; - pstring key_tmp; + char *key_tmp = NULL; char *keyname, *parentpath; - pstring subkeypath; + char *subkeypath = NULL; char *subkeyname; REGISTRY_KEY registry_key; WERROR result = WERR_OK; - - if ( !regfile ) + + if (!regfile) return WERR_GENERAL_FAILURE; - - if ( !keypath ) + + if (!keypath) return WERR_OBJECT_PATH_INVALID; - + /* split up the registry key path */ - - pstrcpy( key_tmp, keypath ); - if ( !reg_split_key( key_tmp, &parentpath, &keyname ) ) + + key_tmp = talloc_strdup(regfile->mem_ctx, keypath); + if (!key_tmp) { + return WERR_NOMEM; + } + if (!reg_split_key( key_tmp, &parentpath, &keyname ) ) return WERR_OBJECT_PATH_INVALID; if ( !keyname ) keyname = parentpath; /* we need a REGISTRY_KEY object here to enumerate subkeys and values */ - + ZERO_STRUCT( registry_key ); 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; /* 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; 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( ®istry_key, values ); /* write out this key */ - + if ( !(key = regfio_write_key( regfile, keyname, values, subkeys, sec_desc, parent )) ) { result = WERR_CAN_NOT_COMPLETE; goto done; @@ -850,7 +880,12 @@ static WERROR reg_write_tree( REGF_FILE *regfile, const char *keypath, num_subkeys = regsubkey_ctr_numkeys( subkeys ); for ( i=0; imem_ctx, + "%s\\%s", keypath, subkeyname); + if (!subkeypath) { + result = WERR_NOMEM; + goto done; + } result = reg_write_tree( regfile, subkeypath, key, sec_desc ); if ( !W_ERROR_IS_OK(result) ) goto done; @@ -915,26 +950,26 @@ static WERROR backup_registry_key ( REGISTRY_KEY *krecord, const char *fname ) SEC_DESC *sd = NULL; /* 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) )) ) { - 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) )); return ( ntstatus_to_werror(map_nt_error_from_unix( errno )) ); } - + if ( !W_ERROR_IS_OK(result = make_default_reg_sd( regfile->mem_ctx, &sd )) ) { regfio_close( regfile ); return result; } - + /* write the registry tree to the file */ - + result = reg_write_tree( regfile, krecord->name, NULL, sd ); - + /* cleanup */ - + regfio_close( regfile ); - + 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) { struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle ); - pstring fname; - int snum; - + char *fname = NULL; + int snum = -1; + if ( !regkey ) - return WERR_BADFID; + return WERR_BADFID; if ( !r->in.filename || !r->in.filename->name ) 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", 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; - + DEBUG(2,("_winreg_SaveKey: Saving [%s] to %s in share %s\n", regkey->key->name, fname, lp_servicename(snum) )); - + return backup_registry_key( regkey->key, fname ); } -- 2.11.4.GIT