diff options
Diffstat (limited to 'source3/rpc_server')
-rw-r--r-- | source3/rpc_server/srv_reg_nt.c | 198 |
1 files changed, 123 insertions, 75 deletions
diff --git a/source3/rpc_server/srv_reg_nt.c b/source3/rpc_server/srv_reg_nt.c index b5511cfceb..d5b2394b40 100644 --- a/source3/rpc_server/srv_reg_nt.c +++ b/source3/rpc_server/srv_reg_nt.c @@ -1,11 +1,11 @@ /* * Unix SMB/CIFS implementation. * RPC Pipe client / server routines - * Copyright (C) Andrew Tridgell 1992-1997, - * Copyright (C) Luke Kenneth Casson Leighton 1996-1997, - * Copyright (C) Paul Ashton 1997. - * Copyright (C) Jeremy Allison 2001. - * Copyright (C) Gerald Carter 2002. + * Copyright (C) Andrew Tridgell 1992-1997. + * Copyright (C) Luke Kenneth Casson Leighton 1996-1997. + * Copyright (C) Paul Ashton 1997. + * Copyright (C) Jeremy Allison 2001. + * Copyright (C) Gerald Carter 2002. * * 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 @@ -33,16 +33,16 @@ ((unsigned int)IVAL((hnd)->data5,4)),((unsigned int)sys_getpid()) -static Registry_Key *regkeys_list; +static REGISTRY_KEY *regkeys_list; /****************************************************************** - free() function for Registry_Key + free() function for REGISTRY_KEY *****************************************************************/ static void free_reg_info(void *ptr) { - Registry_Key *info = (Registry_Key*)ptr; + REGISTRY_KEY *info = (REGISTRY_KEY*)ptr; DLIST_REMOVE(regkeys_list, info); @@ -50,12 +50,12 @@ static void free_reg_info(void *ptr) } /****************************************************************** - Find a registry key handle and return a Registry_Key + Find a registry key handle and return a REGISTRY_KEY *****************************************************************/ -static Registry_Key *find_regkey_index_by_hnd(pipes_struct *p, POLICY_HND *hnd) +static REGISTRY_KEY *find_regkey_index_by_hnd(pipes_struct *p, POLICY_HND *hnd) { - Registry_Key *regkey = NULL; + REGISTRY_KEY *regkey = NULL; if(!find_policy_by_hnd(p,hnd,(void **)®key)) { DEBUG(2,("find_regkey_index_by_hnd: Registry Key not found: ")); @@ -69,34 +69,87 @@ static Registry_Key *find_regkey_index_by_hnd(pipes_struct *p, POLICY_HND *hnd) /******************************************************************* Function for open a new registry handle and creating a handle Note that P should be valid & hnd should already have space + + When we open a key, we store the full path to the key as + HK[LM|U]\<key>\<key>\... *******************************************************************/ -static BOOL open_registry_key(pipes_struct *p, POLICY_HND *hnd, char *name, - uint32 access_granted) +static NTSTATUS open_registry_key(pipes_struct *p, POLICY_HND *hnd, REGISTRY_KEY *parent, + char *subkeyname, uint32 access_granted ) { - Registry_Key *regkey = NULL; + REGISTRY_KEY *regkey = NULL; + pstring parent_keyname; + NTSTATUS result = NT_STATUS_OK; + int num_subkeys; + char *subkeys = NULL; + + if ( parent ) { + pstrcpy( parent_keyname, parent->name ); + pstrcat( parent_keyname, "\\" ); + } + else + *parent_keyname = '\0'; + - DEBUG(7,("open_registry_key: name = [%s]\n", name)); + DEBUG(7,("open_registry_key: name = [%s][%s]\n", parent_keyname, subkeyname)); /* All registry keys **must** have a name of non-zero length */ - if (!name || !*name ) - return False; + if (!subkeyname || !*subkeyname ) + return NT_STATUS_OBJECT_NAME_NOT_FOUND; - if ((regkey=(Registry_Key*)malloc(sizeof(Registry_Key))) == NULL) - return False; + if ((regkey=(REGISTRY_KEY*)malloc(sizeof(REGISTRY_KEY))) == NULL) + return NT_STATUS_NO_MEMORY; ZERO_STRUCTP( regkey ); DLIST_ADD( regkeys_list, regkey ); - /* copy the name and obtain a handle */ + /* copy the name */ + + pstrcpy( regkey->name, parent_keyname ); + pstrcat( regkey->name, subkeyname ); + + /* try to use en existing hook. Otherwise, try to lookup our own */ + + if ( parent && parent->hook ) + regkey->hook = parent->hook; + else + regkey->hook = reghook_cache_find( regkey->name ); + + if ( regkey->hook ) { + DEBUG(10,("open_registry_key: Assigned REGISTRY_HOOK to [%s]\n", + regkey->name )); + } + + /* check if the path really exists...num_subkeys should be >= 0 */ - fstrcpy( regkey->name, name ); + num_subkeys = fetch_reg_keys( regkey, &subkeys ); + + /* if the subkey count failed, bail out */ + + if ( num_subkeys == -1 ) { + SAFE_FREE( regkey ); + + /* don't really know what to return here */ + + result = NT_STATUS_ACCESS_DENIED; + } + else { + /* + * This would previously return NT_STATUS_TOO_MANY_SECRETS + * that doesn't sound quite right to me --jerry + */ + + if ( !create_policy_hnd( p, hnd, free_reg_info, regkey ) ) + result = NT_STATUS_OBJECT_NAME_NOT_FOUND; + } DEBUG(7,("open_registry_key: exit\n")); - return create_policy_hnd( p, hnd, free_reg_info, regkey ); + SAFE_FREE( subkeys ); + + return result; } /******************************************************************* @@ -106,7 +159,7 @@ static BOOL open_registry_key(pipes_struct *p, POLICY_HND *hnd, char *name, static BOOL close_registry_key(pipes_struct *p, POLICY_HND *hnd) { - Registry_Key *regkey = find_regkey_index_by_hnd(p, hnd); + REGISTRY_KEY *regkey = find_regkey_index_by_hnd(p, hnd); if ( !regkey ) { DEBUG(2,("close_registry_key: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd))); @@ -122,7 +175,7 @@ static BOOL close_registry_key(pipes_struct *p, POLICY_HND *hnd) retrieve information about the subkeys *******************************************************************/ -static BOOL get_subkey_information( Registry_Key *key, uint32 *maxnum, uint32 *maxlen ) +static BOOL get_subkey_information( REGISTRY_KEY *key, uint32 *maxnum, uint32 *maxlen ) { int num_subkeys, i; uint32 max_len; @@ -133,7 +186,11 @@ static BOOL get_subkey_information( Registry_Key *key, uint32 *maxnum, uint32 *m if ( !key ) return False; - num_subkeys = fetch_reg_keys( key->name, &subkeys ); + /* first use any registry hook available. + Fall back to tdb if non available */ + + num_subkeys = fetch_reg_keys( key, &subkeys ); + if ( num_subkeys == -1 ) return False; @@ -161,28 +218,36 @@ static BOOL get_subkey_information( Registry_Key *key, uint32 *maxnum, uint32 *m Samba tdb's (such as ntdrivers.tdb). *******************************************************************/ -static BOOL get_value_information( Registry_Key *key, uint32 *maxnum, +static BOOL get_value_information( REGISTRY_KEY *key, uint32 *maxnum, uint32 *maxlen, uint32 *maxsize ) { + REGISTRY_VALUE *val = NULL; + uint32 i, sizemax, lenmax; + int num_values; + if ( !key ) return False; - /* Hard coded key names first */ - /* nothing has valuies right now */ + num_values = fetch_reg_values( key, &val ); + + if ( num_values == -1 ) + return False; + + + lenmax = sizemax = 0; - *maxnum = 0; - *maxlen = 0; - *maxsize = 0; + for ( i=0; i<num_values; i++ ) { + lenmax = MAX(lenmax, strlen(val[i].valuename)+1 ); + sizemax = MAX(sizemax, val[i].size ); + } + + *maxnum = num_values; + *maxlen = lenmax; + *maxsize = sizemax; + + SAFE_FREE( val ); + return True; - -#if 0 /* JERRY */ - /* - * FIXME!!! Need to add routines to look up values in other - * databases --jerry - */ - - return False; -#endif } @@ -208,10 +273,7 @@ NTSTATUS _reg_close(pipes_struct *p, REG_Q_CLOSE *q_u, REG_R_CLOSE *r_u) NTSTATUS _reg_open_hklm(pipes_struct *p, REG_Q_OPEN_HKLM *q_u, REG_R_OPEN_HKLM *r_u) { - if (!open_registry_key(p, &r_u->pol, KEY_HKLM, 0x0)) - return NT_STATUS_OBJECT_NAME_NOT_FOUND; - - return NT_STATUS_OK; + return open_registry_key( p, &r_u->pol, NULL, KEY_HKLM, 0x0 ); } /******************************************************************* @@ -220,10 +282,7 @@ NTSTATUS _reg_open_hklm(pipes_struct *p, REG_Q_OPEN_HKLM *q_u, REG_R_OPEN_HKLM * NTSTATUS _reg_open_hku(pipes_struct *p, REG_Q_OPEN_HKU *q_u, REG_R_OPEN_HKU *r_u) { - if (!open_registry_key(p, &r_u->pol, KEY_HKU, 0x0)) - return NT_STATUS_OBJECT_NAME_NOT_FOUND; - - return NT_STATUS_OK; + return open_registry_key( p, &r_u->pol, NULL, KEY_HKU, 0x0 ); } /******************************************************************* @@ -234,9 +293,8 @@ NTSTATUS _reg_open_entry(pipes_struct *p, REG_Q_OPEN_ENTRY *q_u, REG_R_OPEN_ENTR { POLICY_HND pol; fstring name; - pstring path; - int num_subkeys; - Registry_Key *key = find_regkey_index_by_hnd(p, &q_u->pol); + REGISTRY_KEY *key = find_regkey_index_by_hnd(p, &q_u->pol); + NTSTATUS result; DEBUG(5,("reg_open_entry: Enter\n")); @@ -244,26 +302,14 @@ NTSTATUS _reg_open_entry(pipes_struct *p, REG_Q_OPEN_ENTRY *q_u, REG_R_OPEN_ENTR return NT_STATUS_INVALID_HANDLE; rpcstr_pull(name,q_u->uni_name.buffer,sizeof(name),q_u->uni_name.uni_str_len*2,0); - - /* store the full path in the regkey_list */ - pstrcpy( path, key->name ); - pstrcat( path, "\\" ); - pstrcat( path, name ); - - DEBUG(5,("reg_open_entry: %s\n", path)); - - /* do a check on the name, here */ + DEBUG(5,("reg_open_entry: Enter\n")); - if ( (num_subkeys=fetch_reg_keys_count( path )) == -1 ) - return NT_STATUS_ACCESS_DENIED; - - if (!open_registry_key(p, &pol, path, 0x0)) - return NT_STATUS_TOO_MANY_SECRETS; - - init_reg_r_open_entry(r_u, &pol, NT_STATUS_OK); + result = open_registry_key( p, &pol, key, name, 0x0 ); + + init_reg_r_open_entry( r_u, &pol, result ); - DEBUG(5,("reg_open_entry: Exitn")); + DEBUG(5,("reg_open_entry: Exit\n")); return r_u->status; } @@ -280,7 +326,7 @@ NTSTATUS _reg_info(pipes_struct *p, REG_Q_INFO *q_u, REG_R_INFO *r_u) UNISTR2 *uni_key = NULL; BUFFER2 *buf = NULL; fstring name; - Registry_Key *key = find_regkey_index_by_hnd( p, &q_u->pol ); + REGISTRY_KEY *key = find_regkey_index_by_hnd( p, &q_u->pol ); DEBUG(5,("_reg_info: Enter\n")); @@ -346,7 +392,7 @@ NTSTATUS _reg_info(pipes_struct *p, REG_Q_INFO *q_u, REG_R_INFO *r_u) NTSTATUS _reg_query_key(pipes_struct *p, REG_Q_QUERY_KEY *q_u, REG_R_QUERY_KEY *r_u) { NTSTATUS status = NT_STATUS_OK; - Registry_Key *regkey = find_regkey_index_by_hnd( p, &q_u->pol ); + REGISTRY_KEY *regkey = find_regkey_index_by_hnd( p, &q_u->pol ); DEBUG(5,("_reg_query_key: Enter\n")); @@ -358,6 +404,7 @@ NTSTATUS _reg_query_key(pipes_struct *p, REG_Q_QUERY_KEY *q_u, REG_R_QUERY_KEY * if ( !get_value_information( regkey, &r_u->num_values, &r_u->max_valnamelen, &r_u->max_valbufsize ) ) return NT_STATUS_ACCESS_DENIED; + r_u->sec_desc = 0x00000078; /* size for key's sec_desc */ @@ -379,7 +426,7 @@ NTSTATUS _reg_query_key(pipes_struct *p, REG_Q_QUERY_KEY *q_u, REG_R_QUERY_KEY * NTSTATUS _reg_unknown_1a(pipes_struct *p, REG_Q_UNKNOWN_1A *q_u, REG_R_UNKNOWN_1A *r_u) { NTSTATUS status = NT_STATUS_OK; - Registry_Key *regkey = find_regkey_index_by_hnd( p, &q_u->pol ); + REGISTRY_KEY *regkey = find_regkey_index_by_hnd( p, &q_u->pol ); DEBUG(5,("_reg_unknown_1a: Enter\n")); @@ -401,8 +448,8 @@ NTSTATUS _reg_unknown_1a(pipes_struct *p, REG_Q_UNKNOWN_1A *q_u, REG_R_UNKNOWN_1 NTSTATUS _reg_enum_key(pipes_struct *p, REG_Q_ENUM_KEY *q_u, REG_R_ENUM_KEY *r_u) { NTSTATUS status = NT_STATUS_OK; - Registry_Key *regkey = find_regkey_index_by_hnd( p, &q_u->pol ); - fstring subkey; + REGISTRY_KEY *regkey = find_regkey_index_by_hnd( p, &q_u->pol ); + char *subkey; DEBUG(5,("_reg_enum_key: Enter\n")); @@ -412,9 +459,9 @@ NTSTATUS _reg_enum_key(pipes_struct *p, REG_Q_ENUM_KEY *q_u, REG_R_ENUM_KEY *r_u DEBUG(8,("_reg_enum_key: enumerating key [%s]\n", regkey->name)); - if ( !fetch_reg_keys_specific( regkey->name, subkey, q_u->key_index ) ) + if ( !fetch_reg_keys_specific( regkey, &subkey, q_u->key_index ) ) { - status = werror_to_ntstatus( WERR_NO_MORE_ITEMS ); + status = NT_STATUS_NO_MORE_ENTRIES; goto done; } @@ -427,6 +474,7 @@ NTSTATUS _reg_enum_key(pipes_struct *p, REG_Q_ENUM_KEY *q_u, REG_R_ENUM_KEY *r_u DEBUG(5,("_reg_enum_key: Exit\n")); done: + SAFE_FREE( subkey ); return status; } |