From f65e5c164476b80468aa19452b108db17c642f8b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 24 Jan 2008 11:26:21 +1100 Subject: [PATCH 01/10] Remove useless subs from the ejs provision The less things we manually place into the templates, the easier the conversion to python will be. Andrew Bartlett --- source/scripting/libjs/provision.js | 3 --- source/setup/secrets_dc.ldif | 6 ------ 2 files changed, 9 deletions(-) diff --git a/source/scripting/libjs/provision.js b/source/scripting/libjs/provision.js index 0cca49dec91..175a1782ba1 100644 --- a/source/scripting/libjs/provision.js +++ b/source/scripting/libjs/provision.js @@ -969,9 +969,6 @@ function provision_guess() subobj.ADMINPASS = randpass(12); subobj.LDAPMANAGERPASS = randpass(12); subobj.DEFAULTSITE = "Default-First-Site-Name"; - subobj.NEWGUID = randguid; - subobj.NTTIME = nttime; - subobj.LDAPTIME = ldaptime; subobj.DATESTRING = datestring; subobj.ROOT = findnss(nss.getpwnam, "root"); subobj.NOBODY = findnss(nss.getpwnam, "nobody"); diff --git a/source/setup/secrets_dc.ldif b/source/setup/secrets_dc.ldif index 64469352bbf..71c7fc2f5b9 100644 --- a/source/setup/secrets_dc.ldif +++ b/source/setup/secrets_dc.ldif @@ -7,8 +7,6 @@ realm: ${REALM} secret:: ${MACHINEPASS_B64} secureChannelType: 6 sAMAccountName: ${NETBIOSNAME}$ -whenCreated: ${LDAPTIME} -whenChanged: ${LDAPTIME} msDS-KeyVersionNumber: 1 objectSid: ${DOMAINSID} privateKeytab: ${SECRETS_KEYTAB} @@ -22,8 +20,6 @@ objectClass: kerberosSecret flatname: ${DOMAIN} realm: ${REALM} sAMAccountName: krbtgt -whenCreated: ${LDAPTIME} -whenChanged: ${LDAPTIME} objectSid: ${DOMAINSID} servicePrincipalName: kadmin/changepw krb5Keytab: HDB:ldb:${SAM_LDB}: @@ -36,8 +32,6 @@ objectClass: top objectClass: secret objectClass: kerberosSecret realm: ${REALM} -whenCreated: ${LDAPTIME} -whenChanged: ${LDAPTIME} servicePrincipalName: DNS/${DNSDOMAIN} privateKeytab: ${DNS_KEYTAB} secret:: ${DNSPASS_B64} From e9bb130d63e86fafc4cbf379e2e237354b88bcf8 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 24 Jan 2008 11:33:37 +1100 Subject: [PATCH 02/10] Kill another sub that the modules will handle for us. --- source/scripting/libjs/provision.js | 3 --- source/setup/provision_basedn.ldif | 1 - source/setup/provision_basedn_modify.ldif | 3 --- 3 files changed, 7 deletions(-) diff --git a/source/scripting/libjs/provision.js b/source/scripting/libjs/provision.js index 175a1782ba1..5c4ff6877f2 100644 --- a/source/scripting/libjs/provision.js +++ b/source/scripting/libjs/provision.js @@ -484,9 +484,6 @@ function provision_fix_subobj(subobj, paths) subobj.ADMINPASS_B64 = ldb.encode(subobj.ADMINPASS); subobj.DNSPASS_B64 = ldb.encode(subobj.DNSPASS); - var rdns = split(",", subobj.DOMAINDN); - subobj.RDN_DC = substr(rdns[0], strlen("DC=")); - subobj.SAM_LDB = "tdb://" + paths.samdb; subobj.SECRETS_KEYTAB = paths.keytab; subobj.DNS_KEYTAB = paths.dns_keytab; diff --git a/source/setup/provision_basedn.ldif b/source/setup/provision_basedn.ldif index 3c7537f013a..11eb0593e8d 100644 --- a/source/setup/provision_basedn.ldif +++ b/source/setup/provision_basedn.ldif @@ -6,5 +6,4 @@ objectClass: top objectClass: domain objectClass: domainDNS ${ACI} -dc: ${RDN_DC} diff --git a/source/setup/provision_basedn_modify.ldif b/source/setup/provision_basedn_modify.ldif index fa990599d9a..dadfda720e3 100644 --- a/source/setup/provision_basedn_modify.ldif +++ b/source/setup/provision_basedn_modify.ldif @@ -4,9 +4,6 @@ dn: ${DOMAINDN} changetype: modify - -replace: dc -dc: ${RDN_DC} -- replace: forceLogoff forceLogoff: 9223372036854775808 - From e8fb5da5a18c1c3bd788b1ab3f814ffb847b00fd Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 24 Jan 2008 14:28:25 +1100 Subject: [PATCH 03/10] Use the repl_meta_data module by default. This means that, except when we back onto LDAP, when it will be replaced with the mapping backend, we will keep this codepath tested. Andrew Bartlett --- source/dsdb/samdb/ldb_modules/repl_meta_data.c | 4 ++++ source/scripting/libjs/provision.js | 8 +++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/source/dsdb/samdb/ldb_modules/repl_meta_data.c b/source/dsdb/samdb/ldb_modules/repl_meta_data.c index a21cf250cbf..5100b7cb7c8 100644 --- a/source/dsdb/samdb/ldb_modules/repl_meta_data.c +++ b/source/dsdb/samdb/ldb_modules/repl_meta_data.c @@ -391,6 +391,10 @@ static int replmd_add_originating(struct ldb_module *module, m->originating_usn = seq_num; m->local_usn = seq_num; ni++; + + if (ldb_attr_cmp(e->name, ldb_dn_get_rdn_name(msg->dn))) { + rdn_attr = sa; + } } /* fix meta data count */ diff --git a/source/scripting/libjs/provision.js b/source/scripting/libjs/provision.js index 5c4ff6877f2..b782d948be2 100644 --- a/source/scripting/libjs/provision.js +++ b/source/scripting/libjs/provision.js @@ -693,6 +693,8 @@ function provision(subobj, message, blank, paths, session_info, credentials, lda samdb.set_domain_sid(subobj.DOMAINSID); + samdb.set_ntds_invocationId(subobj.INVOCATIONID); + var load_schema_ok = load_schema(subobj, message, samdb); assert(load_schema_ok.is_ok); @@ -1010,9 +1012,9 @@ function provision_guess() subobj.DOMAINDN_MOD = "pdc_fsmo,password_hash,instancetype"; subobj.CONFIGDN_MOD = "naming_fsmo,instancetype"; subobj.SCHEMADN_MOD = "schema_fsmo,instancetype"; - subobj.DOMAINDN_MOD2 = ",objectguid"; - subobj.CONFIGDN_MOD2 = ",objectguid"; - subobj.SCHEMADN_MOD2 = ",objectguid"; + subobj.DOMAINDN_MOD2 = ",repl_meta_data"; + subobj.CONFIGDN_MOD2 = ",repl_meta_data"; + subobj.SCHEMADN_MOD2 = ",repl_meta_data"; subobj.ACI = "# no aci for local ldb"; From ae2ea1bd0cd2b326b09b372428969f2cf52ce519 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 24 Jan 2008 16:17:45 +1100 Subject: [PATCH 04/10] Make the repl_meta_data module the default for domain controllers. Andrew Bartlett --- source/scripting/libjs/provision.js | 29 ++++++++++++++++++++----- source/setup/provision | 8 +++---- source/setup/provision_partitions.ldif | 6 ++--- source/torture/libnet/libnet_BecomeDC.c | 4 ---- 4 files changed, 31 insertions(+), 16 deletions(-) diff --git a/source/scripting/libjs/provision.js b/source/scripting/libjs/provision.js index b782d948be2..4cb717bde87 100644 --- a/source/scripting/libjs/provision.js +++ b/source/scripting/libjs/provision.js @@ -610,10 +610,21 @@ function provision(subobj, message, blank, paths, session_info, credentials, lda var lp = loadparm_init(); var sys = sys_init(); var info = new Object(); + random_init(local); var ok = provision_fix_subobj(subobj, paths); assert(ok); + if (strlower(subobj.SERVERROLE) == strlower("domain controller")) { + if (subobj.BACKEND_MOD == undefined) { + subobj.BACKEND_MOD = "repl_meta_data"; + } + } else { + if (subobj.BACKEND_MOD == undefined) { + subobj.BACKEND_MOD = "objectguid"; + } + } + if (subobj.DOMAINGUID != undefined) { subobj.DOMAINGUID_MOD = sprintf("replace: objectGUID\nobjectGUID: %s\n-", subobj.DOMAINGUID); } else { @@ -693,7 +704,19 @@ function provision(subobj, message, blank, paths, session_info, credentials, lda samdb.set_domain_sid(subobj.DOMAINSID); - samdb.set_ntds_invocationId(subobj.INVOCATIONID); + if (strlower(subobj.SERVERROLE) == strlower("domain controller")) { + if (subobj.INVOCATIONID == undefined) { + subobj.INVOCATIONID = randguid(); + } + samdb.set_ntds_invocationId(subobj.INVOCATIONID); + if (subobj.BACKEND_MOD == undefined) { + subobj.BACKEND_MOD = "repl_meta_data"; + } + } else { + if (subobj.BACKEND_MOD == undefined) { + subobj.BACKEND_MOD = "objectguid"; + } + } var load_schema_ok = load_schema(subobj, message, samdb); assert(load_schema_ok.is_ok); @@ -960,7 +983,6 @@ function provision_guess() subobj.VERSION = version(); subobj.HOSTIP = hostip(); subobj.DOMAINSID = randsid(); - subobj.INVOCATIONID = randguid(); subobj.POLICYGUID = randguid(); subobj.KRBTGTPASS = randpass(12); subobj.MACHINEPASS = randpass(12); @@ -1012,9 +1034,6 @@ function provision_guess() subobj.DOMAINDN_MOD = "pdc_fsmo,password_hash,instancetype"; subobj.CONFIGDN_MOD = "naming_fsmo,instancetype"; subobj.SCHEMADN_MOD = "schema_fsmo,instancetype"; - subobj.DOMAINDN_MOD2 = ",repl_meta_data"; - subobj.CONFIGDN_MOD2 = ",repl_meta_data"; - subobj.SCHEMADN_MOD2 = ",repl_meta_data"; subobj.ACI = "# no aci for local ldb"; diff --git a/source/setup/provision b/source/setup/provision index 8b24c510401..9e135cddbb4 100755 --- a/source/setup/provision +++ b/source/setup/provision @@ -143,12 +143,10 @@ if (ldapbackend) { subobj.LDAPMODULE = "normalise,entryuuid"; subobj.TDB_MODULES_LIST = ""; } + subobj.BACKEND_MOD = subobj.LDAPMODULE + ",paged_searches"; subobj.DOMAINDN_LDB = subobj.LDAPBACKEND; - subobj.DOMAINDN_MOD2 = "," + subobj.LDAPMODULE + ",paged_searches"; subobj.CONFIGDN_LDB = subobj.LDAPBACKEND; - subobj.CONFIGDN_MOD2 = "," + subobj.LDAPMODULE + ",paged_searches"; subobj.SCHEMADN_LDB = subobj.LDAPBACKEND; - subobj.SCHEMADN_MOD2 = "," + subobj.LDAPMODULE + ",paged_searches"; message("LDAP module: %s on backend: %s\n", subobj.LDAPMODULE, subobj.LDAPBACKEND); } @@ -175,7 +173,9 @@ if (partitions_only) { message("--host-guid='%s' \\\n", subobj.HOSTGUID); } message("--policy-guid='%s' --host-name='%s' --host-ip='%s' \\\n", subobj.POLICYGUID, subobj.HOSTNAME, subobj.HOSTIP); - message("--invocationid='%s' \\\n", subobj.INVOCATIONID); + if (subobj.INVOCATIONID != undefined) { + message("--invocationid='%s' \\\n", subobj.INVOCATIONID); + } message("--adminpass='%s' --krbtgtpass='%s' \\\n", subobj.ADMINPASS, subobj.KRBTGTPASS); message("--machinepass='%s' --dnspass='%s' \\\n", subobj.MACHINEPASS, subobj.DNSPASS); message("--root='%s' --nobody='%s' --nogroup='%s' \\\n", subobj.ROOT, subobj.NOBODY, subobj.NOGROUP); diff --git a/source/setup/provision_partitions.ldif b/source/setup/provision_partitions.ldif index fb8bc7f595c..93fea6bc2d0 100644 --- a/source/setup/provision_partitions.ldif +++ b/source/setup/provision_partitions.ldif @@ -5,9 +5,9 @@ partition: ${DOMAINDN}:${DOMAINDN_LDB} replicateEntries: @ATTRIBUTES replicateEntries: @INDEXLIST replicateEntries: @OPTIONS -modules:${SCHEMADN}:${SCHEMADN_MOD}${SCHEMADN_MOD2} -modules:${CONFIGDN}:${CONFIGDN_MOD}${CONFIGDN_MOD2} -modules:${DOMAINDN}:${DOMAINDN_MOD}${DOMAINDN_MOD2} +modules:${SCHEMADN}:${SCHEMADN_MOD},${BACKEND_MOD} +modules:${CONFIGDN}:${CONFIGDN_MOD},${BACKEND_MOD} +modules:${DOMAINDN}:${DOMAINDN_MOD},${BACKEND_MOD} dn: @MODULES @LIST: ${MODULES_LIST}${TDB_MODULES_LIST},${MODULES_LIST2} diff --git a/source/torture/libnet/libnet_BecomeDC.c b/source/torture/libnet/libnet_BecomeDC.c index 932498a5178..d9645356e81 100644 --- a/source/torture/libnet/libnet_BecomeDC.c +++ b/source/torture/libnet/libnet_BecomeDC.c @@ -201,10 +201,6 @@ static NTSTATUS test_become_dc_prepare_db(void *private_data, "subobj.DOMAIN = \"%s\";\n" "subobj.DEFAULTSITE = \"%s\";\n" "\n" - "subobj.DOMAINDN_MOD2 = \",repl_meta_data\";\n" - "subobj.CONFIGDN_MOD2 = \",repl_meta_data\";\n" - "subobj.SCHEMADN_MOD2 = \",repl_meta_data\";\n" - "\n" "subobj.KRBTGTPASS = \"_NOT_USED_\";\n" "subobj.MACHINEPASS = \"%s\";\n" "subobj.ADMINPASS = \"_NOT_USED_\";\n" From be5eb2da241452ccc0526f4f115aa44c0793c351 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 24 Jan 2008 16:25:35 +1100 Subject: [PATCH 05/10] Ensure we set subobj.BACKEND_MOD for the 'partitions only' case. Andrew Bartlett --- source/scripting/libjs/provision.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/scripting/libjs/provision.js b/source/scripting/libjs/provision.js index 4cb717bde87..e71498010cf 100644 --- a/source/scripting/libjs/provision.js +++ b/source/scripting/libjs/provision.js @@ -524,6 +524,10 @@ function provision_become_dc(subobj, message, erase, paths, session_info) var ok = provision_fix_subobj(subobj, paths); assert(ok); + if (subobj.BACKEND_MOD == undefined) { + subobj.BACKEND_MOD = "repl_meta_data"; + } + info.subobj = subobj; info.message = message; info.session_info = session_info; From 3c5bae2249d01213ff4bd7df2b4e3ac04da4a52d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 24 Jan 2008 10:22:45 +0100 Subject: [PATCH 06/10] netlogon.idl: remove unused netr_GroupsMembership structure We have samr_RidWithAttribute and use that in all cases. metze --- source/librpc/idl/netlogon.idl | 5 ----- 1 file changed, 5 deletions(-) diff --git a/source/librpc/idl/netlogon.idl b/source/librpc/idl/netlogon.idl index dcbb647ba01..3ca65471060 100644 --- a/source/librpc/idl/netlogon.idl +++ b/source/librpc/idl/netlogon.idl @@ -126,11 +126,6 @@ interface netlogon [case(6)] netr_NetworkInfo *network; } netr_LogonLevel; - typedef [public] struct { - uint32 rid; - uint32 attributes; - } netr_GroupMembership; - typedef [public,flag(NDR_PAHEX)] struct { uint8 key[16]; } netr_UserSessionKey; From 6d68161e676d381600c77c3f862bd7e013968724 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 24 Jan 2008 10:24:41 +0100 Subject: [PATCH 07/10] netlogon.idl: make use of bitmap samr_GroupAttrs metze --- source/auth/auth_sam_reply.c | 2 +- source/librpc/idl/netlogon.idl | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/source/auth/auth_sam_reply.c b/source/auth/auth_sam_reply.c index 6ab220498dc..ea6f0a1f60e 100644 --- a/source/auth/auth_sam_reply.c +++ b/source/auth/auth_sam_reply.c @@ -132,7 +132,7 @@ NTSTATUS auth_convert_server_info_saminfo3(TALLOC_CTX *mem_ctx, continue; } sam3->sids[sam3->sidcount].sid = talloc_reference(sam3->sids,server_info->domain_groups[i]); - sam3->sids[sam3->sidcount].attribute = + sam3->sids[sam3->sidcount].attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED; sam3->sidcount += 1; } diff --git a/source/librpc/idl/netlogon.idl b/source/librpc/idl/netlogon.idl index 3ca65471060..63e7aaf553e 100644 --- a/source/librpc/idl/netlogon.idl +++ b/source/librpc/idl/netlogon.idl @@ -19,6 +19,7 @@ import "lsa.idl", "samr.idl", "security.idl", "nbt.idl"; interface netlogon { typedef bitmap samr_AcctFlags samr_AcctFlags; + typedef bitmap samr_GroupAttrs samr_GroupAttrs; /*****************/ /* Function 0x00 */ @@ -182,7 +183,7 @@ interface netlogon typedef struct { dom_sid2 *sid; - uint32 attribute; + samr_GroupAttrs attributes; } netr_SidAttr; typedef [public] struct { From 7222edb9cde5cdeb9d065e890775a7254b26648f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 24 Jan 2008 13:52:47 +0100 Subject: [PATCH 08/10] netlogon.idl: add some MSV1_0_ values from samba3 and use a bitmap32 metze --- source/librpc/idl/netlogon.idl | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/source/librpc/idl/netlogon.idl b/source/librpc/idl/netlogon.idl index 63e7aaf553e..3e4d46d7f72 100644 --- a/source/librpc/idl/netlogon.idl +++ b/source/librpc/idl/netlogon.idl @@ -87,13 +87,18 @@ interface netlogon [size_is(size/2),length_is(length/2)] uint16 *bindata; } netr_AcctLockStr; - const int MSV1_0_CLEARTEXT_PASSWORD_ALLOWED = 0x002; - const int MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT = 0x020; - const int MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT = 0x800; + typedef [public,bitmap32bit] bitmap { + MSV1_0_CLEARTEXT_PASSWORD_ALLOWED = 0x00000002, + MSV1_0_UPDATE_LOGON_STATISTICS = 0x00000004, + MSV1_0_RETURN_USER_PARAMETERS = 0x00000008, + MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT = 0x00000020, + MSV1_0_RETURN_PROFILE_PATH = 0x00000200, + MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT = 0x00000800 + } netr_LogonParameterControl; typedef struct { lsa_String domain_name; - uint32 parameter_control; /* see MSV1_0_* */ + netr_LogonParameterControl parameter_control; /* see MSV1_0_* */ uint32 logon_id_low; uint32 logon_id_high; lsa_String account_name; From c1ac13ee12d6d7e41b3700f207c9a8811bb05cd4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 24 Jan 2008 14:57:30 +0100 Subject: [PATCH 09/10] pidl/Samba4::Header: we don't need to check if (defined($enum->{ELEMENTS})) twice metze --- source/pidl/lib/Parse/Pidl/Samba4/Header.pm | 38 ++++++++++----------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/source/pidl/lib/Parse/Pidl/Samba4/Header.pm b/source/pidl/lib/Parse/Pidl/Samba4/Header.pm index 2b3a9df80f3..b2d5126d1d9 100644 --- a/source/pidl/lib/Parse/Pidl/Samba4/Header.pm +++ b/source/pidl/lib/Parse/Pidl/Samba4/Header.pm @@ -131,27 +131,25 @@ sub HeaderEnum($$) my $count = 0; my $with_val = 0; my $without_val = 0; - if (defined($enum->{ELEMENTS})) { - pidl " { __donnot_use_enum_$name=0x7FFFFFFF}\n"; - foreach my $e (@{$enum->{ELEMENTS}}) { - my $t = "$e"; - my $name; - my $value; - if ($t =~ /(.*)=(.*)/) { - $name = $1; - $value = $2; - $with_val = 1; - fatal($e->{ORIGINAL}, "you can't mix enum member with values and without values!") - unless ($without_val == 0); - } else { - $name = $t; - $value = $count++; - $without_val = 1; - fatal($e->{ORIGINAL}, "you can't mix enum member with values and without values!") - unless ($with_val == 0); - } - pidl "#define $name ( $value )\n"; + pidl " { __donnot_use_enum_$name=0x7FFFFFFF}\n"; + foreach my $e (@{$enum->{ELEMENTS}}) { + my $t = "$e"; + my $name; + my $value; + if ($t =~ /(.*)=(.*)/) { + $name = $1; + $value = $2; + $with_val = 1; + fatal($e->{ORIGINAL}, "you can't mix enum member with values and without values!") + unless ($without_val == 0); + } else { + $name = $t; + $value = $count++; + $without_val = 1; + fatal($e->{ORIGINAL}, "you can't mix enum member with values and without values!") + unless ($with_val == 0); } + pidl "#define $name ( $value )\n"; } pidl "#endif\n"; } From dd77fc45eee2dde7bdd31a2e39387e94cec158aa Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 24 Jan 2008 15:04:58 +0100 Subject: [PATCH 10/10] pidl: get rid of stupid ';' char to terminate bitmap defines metze --- source/pidl/lib/Parse/Pidl/Samba4/Header.pm | 45 ++++++++++----------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/source/pidl/lib/Parse/Pidl/Samba4/Header.pm b/source/pidl/lib/Parse/Pidl/Samba4/Header.pm index b2d5126d1d9..14f472340c6 100644 --- a/source/pidl/lib/Parse/Pidl/Samba4/Header.pm +++ b/source/pidl/lib/Parse/Pidl/Samba4/Header.pm @@ -82,9 +82,9 @@ sub HeaderElement($) ##################################################################### # parse a struct -sub HeaderStruct($$) +sub HeaderStruct($$;$) { - my($struct,$name) = @_; + my($struct,$name,$tail) = @_; pidl "struct $name"; return if (not defined($struct->{ELEMENTS})); pidl " {\n"; @@ -103,13 +103,14 @@ sub HeaderStruct($$) if (defined $struct->{PROPERTIES}) { HeaderProperties($struct->{PROPERTIES}, []); } + pidl $tail if defined($tail); } ##################################################################### # parse a enum -sub HeaderEnum($$) +sub HeaderEnum($$;$) { - my($enum,$name) = @_; + my($enum,$name,$tail) = @_; my $first = 1; pidl "enum $name"; @@ -153,6 +154,7 @@ sub HeaderEnum($$) } pidl "#endif\n"; } + pidl $tail if defined($tail); } ##################################################################### @@ -170,9 +172,9 @@ sub HeaderBitmap($$) ##################################################################### # parse a union -sub HeaderUnion($$) +sub HeaderUnion($$;$) { - my($union,$name) = @_; + my($union,$name,$tail) = @_; my %done = (); pidl "union $name"; @@ -193,18 +195,19 @@ sub HeaderUnion($$) if (defined $union->{PROPERTIES}) { HeaderProperties($union->{PROPERTIES}, []); } + pidl $tail if defined($tail); } ##################################################################### # parse a type -sub HeaderType($$$) +sub HeaderType($$$;$) { - my($e,$data,$name) = @_; + my($e,$data,$name,$tail) = @_; if (ref($data) eq "HASH") { - ($data->{TYPE} eq "ENUM") && HeaderEnum($data, $name); + ($data->{TYPE} eq "ENUM") && HeaderEnum($data, $name, $tail); ($data->{TYPE} eq "BITMAP") && HeaderBitmap($data, $name); - ($data->{TYPE} eq "STRUCT") && HeaderStruct($data, $name); - ($data->{TYPE} eq "UNION") && HeaderUnion($data, $name); + ($data->{TYPE} eq "STRUCT") && HeaderStruct($data, $name, $tail); + ($data->{TYPE} eq "UNION") && HeaderUnion($data, $name, $tail); return; } @@ -213,14 +216,15 @@ sub HeaderType($$$) } else { pidl mapTypeName($e->{TYPE}); } + pidl $tail if defined($tail); } ##################################################################### # parse a typedef -sub HeaderTypedef($) +sub HeaderTypedef($;$) { - my($typedef) = shift; - HeaderType($typedef, $typedef->{DATA}, $typedef->{NAME}) if defined ($typedef->{DATA}); + my($typedef,$tail) = @_; + HeaderType($typedef, $typedef->{DATA}, $typedef->{NAME}, $tail) if defined ($typedef->{DATA}); } ##################################################################### @@ -357,16 +361,11 @@ sub HeaderInterface($) } foreach my $t (@{$interface->{TYPES}}) { - HeaderTypedef($t) if ($t->{TYPE} eq "TYPEDEF"); - HeaderStruct($t, $t->{NAME}) if ($t->{TYPE} eq "STRUCT"); - HeaderUnion($t, $t->{NAME}) if ($t->{TYPE} eq "UNION"); - HeaderEnum($t, $t->{NAME}) if ($t->{TYPE} eq "ENUM"); + HeaderTypedef($t, ";\n\n") if ($t->{TYPE} eq "TYPEDEF"); + HeaderStruct($t, $t->{NAME}, ";\n\n") if ($t->{TYPE} eq "STRUCT"); + HeaderUnion($t, $t->{NAME}, ";\n\n") if ($t->{TYPE} eq "UNION"); + HeaderEnum($t, $t->{NAME}, ";\n\n") if ($t->{TYPE} eq "ENUM"); HeaderBitmap($t, $t->{NAME}) if ($t->{TYPE} eq "BITMAP"); - pidl ";\n\n" if ($t->{TYPE} eq "BITMAP" or - $t->{TYPE} eq "STRUCT" or - $t->{TYPE} eq "TYPEDEF" or - $t->{TYPE} eq "UNION" or - $t->{TYPE} eq "ENUM"); } foreach my $fn (@{$interface->{FUNCTIONS}}) {