summaryrefslogtreecommitdiff
path: root/source3/rpc_server
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2002-07-24 06:42:09 +0000
committerGerald Carter <jerry@samba.org>2002-07-24 06:42:09 +0000
commitc808cc3643f06c72f870d0b14a37c7a46627e2fa (patch)
treeba307c845f17a592388770b115322855d56fe888 /source3/rpc_server
parent84f2875d7bac30e75397bbf89d3d5e79ba790ddc (diff)
downloadsamba-c808cc3643f06c72f870d0b14a37c7a46627e2fa.tar.gz
samba-c808cc3643f06c72f870d0b14a37c7a46627e2fa.tar.bz2
samba-c808cc3643f06c72f870d0b14a37c7a46627e2fa.zip
several changes in this checkin
* added REG_OPEN_HKCR for supporting regedit.exe * All data n a REGISTRY_VALUE is stored to a pointer now * fixed REG_INFO to correctly display data when double clicking on and entry in the registry editor * Will now enumerate installed driver_info_3 data * fixed numerous bugs related to pointer offsets, memory issues, etc.. in the registry routines * added a simple caching mechanism to fetch_reg_[keys|values]_specific() All that is left now is to enumerate PrinterData and I will have finished what I started out to do.... (This used to be commit 419d7208e8384e4ad2c4dd328ad5e630971bc76c)
Diffstat (limited to 'source3/rpc_server')
-rw-r--r--source3/rpc_server/srv_reg.c29
-rw-r--r--source3/rpc_server/srv_reg_nt.c154
2 files changed, 119 insertions, 64 deletions
diff --git a/source3/rpc_server/srv_reg.c b/source3/rpc_server/srv_reg.c
index ee873e32e9..cb96005db1 100644
--- a/source3/rpc_server/srv_reg.c
+++ b/source3/rpc_server/srv_reg.c
@@ -83,7 +83,7 @@ static BOOL api_reg_open_hklm(pipes_struct *p)
}
/*******************************************************************
- api_reg_open_khlm
+ api_reg_open_khu
********************************************************************/
static BOOL api_reg_open_hku(pipes_struct *p)
@@ -108,6 +108,32 @@ static BOOL api_reg_open_hku(pipes_struct *p)
return True;
}
+/*******************************************************************
+ api_reg_open_khcr
+ ********************************************************************/
+
+static BOOL api_reg_open_hkcr(pipes_struct *p)
+{
+ REG_Q_OPEN_HKCR q_u;
+ REG_R_OPEN_HKCR r_u;
+ prs_struct *data = &p->in_data.data;
+ prs_struct *rdata = &p->out_data.rdata;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ /* grab the reg open */
+ if(!reg_io_q_open_hkcr("", &q_u, data, 0))
+ return False;
+
+ r_u.status = _reg_open_hkcr(p, &q_u, &r_u);
+
+ if(!reg_io_r_open_hkcr("", &r_u, rdata, 0))
+ return False;
+
+ return True;
+}
+
/*******************************************************************
api_reg_open_entry
@@ -324,6 +350,7 @@ static struct api_struct api_reg_cmds[] =
{
{ "REG_CLOSE" , REG_CLOSE , api_reg_close },
{ "REG_OPEN_ENTRY" , REG_OPEN_ENTRY , api_reg_open_entry },
+ { "REG_OPEN_HKCR" , REG_OPEN_HKCR , api_reg_open_hkcr },
{ "REG_OPEN_HKLM" , REG_OPEN_HKLM , api_reg_open_hklm },
{ "REG_OPEN_HKU" , REG_OPEN_HKU , api_reg_open_hku },
{ "REG_ENUM_KEY" , REG_ENUM_KEY , api_reg_enum_key },
diff --git a/source3/rpc_server/srv_reg_nt.c b/source3/rpc_server/srv_reg_nt.c
index 99439bcc38..3afb2a2c81 100644
--- a/source3/rpc_server/srv_reg_nt.c
+++ b/source3/rpc_server/srv_reg_nt.c
@@ -78,33 +78,35 @@ static NTSTATUS open_registry_key(pipes_struct *p, POLICY_HND *hnd, REGISTRY_KEY
char *subkeyname, uint32 access_granted )
{
REGISTRY_KEY *regkey = NULL;
- pstring parent_keyname;
NTSTATUS result = NT_STATUS_OK;
REGSUBKEY_CTR subkeys;
- if ( parent ) {
- pstrcpy( parent_keyname, parent->name );
- pstrcat( parent_keyname, "\\" );
- }
- else
- *parent_keyname = '\0';
-
- DEBUG(7,("open_registry_key: name = [%s][%s]\n", parent_keyname, subkeyname));
+ DEBUG(7,("open_registry_key: name = [%s][%s]\n",
+ parent ? parent->name : "NULL", subkeyname));
- /* All registry keys **must** have a name of non-zero length */
-
- if (!subkeyname || !*subkeyname )
- return NT_STATUS_OBJECT_NAME_NOT_FOUND;
-
if ((regkey=(REGISTRY_KEY*)malloc(sizeof(REGISTRY_KEY))) == NULL)
return NT_STATUS_NO_MEMORY;
ZERO_STRUCTP( regkey );
- /* copy the name */
+ /*
+ * very crazy, but regedit.exe on Win2k will attempt to call
+ * REG_OPEN_ENTRY with a keyname of "". We should return a new
+ * (second) handle here on the key->name. regedt32.exe does
+ * not do this stupidity. --jerry
+ */
- pstrcpy( regkey->name, parent_keyname );
- pstrcat( regkey->name, subkeyname );
+ if (!subkeyname || !*subkeyname ) {
+ pstrcpy( regkey->name, parent->name );
+ }
+ else {
+ pstrcpy( regkey->name, "" );
+ if ( parent ) {
+ pstrcat( regkey->name, parent->name );
+ pstrcat( regkey->name, "\\" );
+ }
+ pstrcat( regkey->name, subkeyname );
+ }
/* Look up the table of registry I/O operations */
@@ -227,7 +229,8 @@ static BOOL get_value_information( REGISTRY_KEY *key, uint32 *maxnum,
if ( !key )
return False;
- ZERO_STRUCTP( &val );
+
+ ZERO_STRUCTP( &values );
regval_ctr_init( &values );
@@ -274,7 +277,6 @@ NTSTATUS _reg_close(pipes_struct *p, REG_Q_CLOSE *q_u, REG_R_CLOSE *r_u)
}
/*******************************************************************
- reg_reply_open
********************************************************************/
NTSTATUS _reg_open_hklm(pipes_struct *p, REG_Q_OPEN_HKLM *q_u, REG_R_OPEN_HKLM *r_u)
@@ -283,7 +285,14 @@ NTSTATUS _reg_open_hklm(pipes_struct *p, REG_Q_OPEN_HKLM *q_u, REG_R_OPEN_HKLM *
}
/*******************************************************************
- reg_reply_open
+ ********************************************************************/
+
+NTSTATUS _reg_open_hkcr(pipes_struct *p, REG_Q_OPEN_HKCR *q_u, REG_R_OPEN_HKCR *r_u)
+{
+ return open_registry_key( p, &r_u->pol, NULL, KEY_HKCR, 0x0 );
+}
+
+/*******************************************************************
********************************************************************/
NTSTATUS _reg_open_hku(pipes_struct *p, REG_Q_OPEN_HKU *q_u, REG_R_OPEN_HKU *r_u)
@@ -310,7 +319,7 @@ NTSTATUS _reg_open_entry(pipes_struct *p, REG_Q_OPEN_ENTRY *q_u, REG_R_OPEN_ENTR
rpcstr_pull(name,q_u->uni_name.buffer,sizeof(name),q_u->uni_name.uni_str_len*2,0);
DEBUG(5,("reg_open_entry: Enter\n"));
-
+
result = open_registry_key( p, &pol, key, name, 0x0 );
init_reg_r_open_entry( r_u, &pol, result );
@@ -326,64 +335,83 @@ NTSTATUS _reg_open_entry(pipes_struct *p, REG_Q_OPEN_ENTRY *q_u, REG_R_OPEN_ENTR
NTSTATUS _reg_info(pipes_struct *p, REG_Q_INFO *q_u, REG_R_INFO *r_u)
{
- NTSTATUS status = NT_STATUS_OK;
- char *value = NULL;
- uint32 type = 0x1; /* key type: REG_SZ */
- UNISTR2 *uni_key = NULL;
- BUFFER2 *buf = NULL;
- fstring name;
- REGISTRY_KEY *key = find_regkey_index_by_hnd( p, &q_u->pol );
+ NTSTATUS status = NT_STATUS_NO_SUCH_FILE;
+ fstring name;
+ REGISTRY_KEY *regkey = find_regkey_index_by_hnd( p, &q_u->pol );
+ REGISTRY_VALUE *val = NULL;
+ REGISTRY_VALUE emptyval;
+ REGVAL_CTR regvals;
+ int i;
DEBUG(5,("_reg_info: Enter\n"));
- if ( !key )
+ if ( !regkey )
return NT_STATUS_INVALID_HANDLE;
- DEBUG(7,("_reg_info: policy key name = [%s]\n", key->name));
-
+ DEBUG(7,("_reg_info: policy key name = [%s]\n", regkey->name));
+
rpcstr_pull(name, q_u->uni_type.buffer, sizeof(name), q_u->uni_type.uni_str_len*2, 0);
- DEBUG(5,("reg_info: checking subkey: %s\n", name));
-
- uni_key = (UNISTR2 *)talloc_zero(p->mem_ctx, sizeof(UNISTR2));
- buf = (BUFFER2 *)talloc_zero(p->mem_ctx, sizeof(BUFFER2));
+ DEBUG(5,("reg_info: looking up value: [%s]\n", name));
- if (!uni_key || !buf)
- return NT_STATUS_NO_MEMORY;
+ ZERO_STRUCTP( &regvals );
+
+ regval_ctr_init( &regvals );
+ /* couple of hard coded registry values */
+
if ( strequal(name, "RefusePasswordChange") ) {
- type=0xF770;
- status = NT_STATUS_NO_SUCH_FILE;
- init_unistr2(uni_key, "", 0);
- init_buffer2(buf, (uint8*) uni_key->buffer, uni_key->uni_str_len*2);
-
- buf->buf_max_len=4;
+ ZERO_STRUCTP( &emptyval );
+ val = &emptyval;
+
+ goto out;
+ }
+ if ( strequal(name, "ProductType") ) {
+ /* This makes the server look like a member server to clients */
+ /* which tells clients that we have our own local user and */
+ /* group databases and helps with ACL support. */
+
+ switch (lp_server_role()) {
+ case ROLE_DOMAIN_PDC:
+ case ROLE_DOMAIN_BDC:
+ regval_ctr_addvalue( &regvals, "ProductType", REG_SZ, "LanmanNT", strlen("LanmanNT")+1 );
+ break;
+ case ROLE_STANDALONE:
+ regval_ctr_addvalue( &regvals, "ProductType", REG_SZ, "ServerNT", strlen("ServerNT")+1 );
+ break;
+ case ROLE_DOMAIN_MEMBER:
+ regval_ctr_addvalue( &regvals, "ProductType", REG_SZ, "WinNT", strlen("WinNT")+1 );
+ break;
+ }
+
+ val = regval_ctr_specific_value( &regvals, 0 );
+
+ status = NT_STATUS_OK;
+
goto out;
}
- switch (lp_server_role()) {
- case ROLE_DOMAIN_PDC:
- case ROLE_DOMAIN_BDC:
- value = "LanmanNT";
- break;
- case ROLE_STANDALONE:
- value = "ServerNT";
- break;
- case ROLE_DOMAIN_MEMBER:
- value = "WinNT";
+ /* else fall back to actually looking up the value */
+
+ for ( i=0; fetch_reg_values_specific(regkey, &val, i); i++ )
+ {
+ DEBUG(10,("_reg_info: Testing value [%s]\n", val->valuename));
+ if ( StrCaseCmp( val->valuename, name ) == 0 ) {
+ DEBUG(10,("_reg_info: Found match for value [%s]\n", name));
+ status = NT_STATUS_OK;
break;
+ }
+
+ free_registry_value( val );
}
- /* This makes the server look like a member server to clients */
- /* which tells clients that we have our own local user and */
- /* group databases and helps with ACL support. */
-
- init_unistr2(uni_key, value, strlen(value)+1);
- init_buffer2(buf, (uint8*)uni_key->buffer, uni_key->uni_str_len*2);
- out:
- init_reg_r_info(q_u->ptr_buf, r_u, buf, type, status);
+out:
+ new_init_reg_r_info(q_u->ptr_buf, r_u, val, status);
+
+ regval_ctr_destroy( &regvals );
+ free_registry_value( val );
DEBUG(5,("_reg_info: Exit\n"));
@@ -455,7 +483,7 @@ 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 );
- char *subkey;
+ char *subkey = NULL;
DEBUG(5,("_reg_enum_key: Enter\n"));
@@ -518,7 +546,7 @@ NTSTATUS _reg_enum_value(pipes_struct *p, REG_Q_ENUM_VALUE *q_u, REG_R_ENUM_VALU
DEBUG(5,("_reg_enum_value: Exit\n"));
done:
- SAFE_FREE( val );
+ free_registry_value( val );
return status;
}