* got rid of UNISTR2 and everything that depends on it
authorAndrew Tridgell <tridge@samba.org>
Mon, 1 Dec 2003 00:17:30 +0000 (00:17 +0000)
committerAndrew Tridgell <tridge@samba.org>
Mon, 1 Dec 2003 00:17:30 +0000 (00:17 +0000)
  * removed a bunch of code that needs to be rewritten using the new
    interfaces
(This used to be commit 9b02b486ef5906516f8cad79dbff5e3dd54cde66)

15 files changed:
source4/Makefile.in
source4/auth/auth_util.c
source4/groupdb/mapping.c [deleted file]
source4/include/auth.h
source4/include/mapping.h
source4/include/rpc_dce.h
source4/include/rpc_lsa.h
source4/include/rpc_misc.h
source4/include/rpc_netlogon.h
source4/lib/util_unistr.c
source4/libcli/auth/ntlmssp.h
source4/libcli/util/credentials.c
source4/passdb/pdb_interface.c
source4/printing/nt_printing.c [deleted file]
source4/registry/reg_printing.c [deleted file]

index 6a9017bbe155ef6c37b5fc61eb9a5e65b6fad621..f0e9574f4bea6640fba7fc492cbb2c1a36abebcc 100644 (file)
@@ -244,8 +244,6 @@ DEVEL_HELP_OBJ = modules/developer.o
 
 
 
-GROUPDB_OBJ = groupdb/mapping.o
-
 #PROFILE_OBJ = profile/profile.o
 
 # OPLOCK_OBJ = smbd/oplock.o smbd/oplock_irix.o smbd/oplock_linux.o
index 580b96142e1d1697214c130f7d3348e0953e4a4f..db208008aef781e56cf2b04913ffd96444e10ac8 100644 (file)
@@ -862,228 +862,6 @@ NTSTATUS make_server_info_guest(auth_serversupplied_info **server_info)
        return nt_status;
 }
 
-/***************************************************************************
- Make a server_info struct from the info3 returned by a domain logon 
-***************************************************************************/
-
-NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, 
-                               const char *internal_username,
-                               const char *sent_nt_username,
-                               const char *domain,
-                               auth_serversupplied_info **server_info, 
-                               NET_USER_INFO_3 *info3) 
-{
-       NTSTATUS nt_status = NT_STATUS_OK;
-
-       const char *nt_domain;
-       const char *nt_username;
-
-       SAM_ACCOUNT *sam_account = NULL;
-       DOM_SID user_sid;
-       DOM_SID group_sid;
-
-       struct passwd *passwd;
-
-       uid_t uid;
-       gid_t gid;
-
-       int n_lgroupSIDs;
-       DOM_SID *lgroupSIDs   = NULL;
-
-       gid_t *unix_groups = NULL;
-       NT_USER_TOKEN *token;
-
-       DOM_SID *all_group_SIDs;
-       size_t i;
-
-       /* 
-          Here is where we should check the list of
-          trusted domains, and verify that the SID 
-          matches.
-       */
-
-       sid_copy(&user_sid, &info3->dom_sid.sid);
-       if (!sid_append_rid(&user_sid, info3->user_rid)) {
-               return NT_STATUS_INVALID_PARAMETER;
-       }
-       
-       sid_copy(&group_sid, &info3->dom_sid.sid);
-       if (!sid_append_rid(&group_sid, info3->group_rid)) {
-               return NT_STATUS_INVALID_PARAMETER;
-       }
-
-       if (!(nt_username = unistr2_tdup(mem_ctx, &(info3->uni_user_name)))) {
-               /* If the server didn't give us one, just use the one we sent them */
-               nt_username = sent_nt_username;
-       }
-
-       if (!(nt_domain = unistr2_tdup(mem_ctx, &(info3->uni_logon_dom)))) {
-               /* If the server didn't give us one, just use the one we sent them */
-               domain = domain;
-       }
-
-       if (winbind_sid_to_uid(&uid, &user_sid) 
-           && winbind_sid_to_gid(&gid, &group_sid) 
-           && ((passwd = getpwuid_alloc(uid)))) {
-               nt_status = pdb_init_sam_pw(&sam_account, passwd);
-               passwd_free(&passwd);
-       } else {
-               char *dom_user;
-               dom_user = talloc_asprintf(mem_ctx, "%s%s%s", 
-                                          nt_domain,
-                                          lp_winbind_separator(),
-                                          internal_username);
-               
-               if (!dom_user) {
-                       DEBUG(0, ("talloc_asprintf failed!\n"));
-                       return NT_STATUS_NO_MEMORY;
-               } else { 
-               
-                       if (!(passwd = Get_Pwnam(dom_user))
-                               /* Only lookup local for the local
-                                  domain, we don't want this for
-                                  trusted domains */
-                           && strequal(nt_domain, lp_workgroup())) {
-                               passwd = Get_Pwnam(internal_username);
-                       }
-                           
-                       if (!passwd) {
-                               return NT_STATUS_NO_SUCH_USER;
-                       } else {
-                               nt_status = pdb_init_sam_pw(&sam_account, passwd);
-                       }
-               }
-       }
-       
-       if (!NT_STATUS_IS_OK(nt_status)) {
-               DEBUG(0, ("make_server_info_info3: pdb_init_sam failed!\n"));
-               return nt_status;
-       }
-               
-       if (!pdb_set_user_sid(sam_account, &user_sid, PDB_CHANGED)) {
-               pdb_free_sam(&sam_account);
-               return NT_STATUS_UNSUCCESSFUL;
-       }
-
-       if (!pdb_set_group_sid(sam_account, &group_sid, PDB_CHANGED)) {
-               pdb_free_sam(&sam_account);
-               return NT_STATUS_UNSUCCESSFUL;
-       }
-               
-       if (!pdb_set_nt_username(sam_account, nt_username, PDB_CHANGED)) {
-               pdb_free_sam(&sam_account);
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       if (!pdb_set_domain(sam_account, nt_domain, PDB_CHANGED)) {
-               pdb_free_sam(&sam_account);
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       if (!pdb_set_fullname(sam_account, unistr2_static(mem_ctx, &(info3->uni_full_name)), PDB_CHANGED)) {
-               pdb_free_sam(&sam_account);
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       if (!pdb_set_logon_script(sam_account, unistr2_static(mem_ctx, &(info3->uni_logon_script)), PDB_CHANGED)) {
-               pdb_free_sam(&sam_account);
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       if (!pdb_set_profile_path(sam_account, unistr2_static(mem_ctx, &(info3->uni_profile_path)), PDB_CHANGED)) {
-               pdb_free_sam(&sam_account);
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       if (!pdb_set_homedir(sam_account, unistr2_static(mem_ctx, &(info3->uni_home_dir)), PDB_CHANGED)) {
-               pdb_free_sam(&sam_account);
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       if (!pdb_set_dir_drive(sam_account, unistr2_static(mem_ctx, &(info3->uni_dir_drive)), PDB_CHANGED)) {
-               pdb_free_sam(&sam_account);
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       if (!NT_STATUS_IS_OK(nt_status = make_server_info(server_info, sam_account))) {
-               DEBUG(4, ("make_server_info failed!\n"));
-               pdb_free_sam(&sam_account);
-               return nt_status;
-       }
-
-       /* Store the user group information in the server_info 
-          returned to the caller. */
-       
-       if (!NT_STATUS_IS_OK(nt_status 
-                            = get_user_groups_from_local_sam(sam_account, 
-                                                             &n_lgroupSIDs, 
-                                                             &lgroupSIDs, 
-                                                             &unix_groups)))
-       {
-               DEBUG(4,("get_user_groups_from_local_sam failed\n"));
-               return nt_status;
-       }
-
-       (*server_info)->groups = unix_groups;
-       (*server_info)->n_groups = n_lgroupSIDs;
-       
-       /* Create a 'combined' list of all SIDs we might want in the SD */
-       all_group_SIDs   = malloc(sizeof(DOM_SID) * 
-                                 (n_lgroupSIDs + info3->num_groups2 +
-                                  info3->num_other_sids));
-       if (!all_group_SIDs) {
-               DEBUG(0, ("create_nt_token_info3: malloc() failed for DOM_SID list!\n"));
-               SAFE_FREE(lgroupSIDs);
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       /* Copy the 'local' sids */
-       memcpy(all_group_SIDs, lgroupSIDs, sizeof(DOM_SID) * n_lgroupSIDs);
-       SAFE_FREE(lgroupSIDs);
-
-       /* and create (by appending rids) the 'domain' sids */
-       for (i = 0; i < info3->num_groups2; i++) {
-               sid_copy(&all_group_SIDs[i+n_lgroupSIDs], &(info3->dom_sid.sid));
-               if (!sid_append_rid(&all_group_SIDs[i+n_lgroupSIDs], info3->gids[i].g_rid)) {
-                       nt_status = NT_STATUS_INVALID_PARAMETER;
-                       DEBUG(3,("create_nt_token_info3: could not append additional group rid 0x%x\n",
-                               info3->gids[i].g_rid));                 
-                       SAFE_FREE(lgroupSIDs);
-                       return nt_status;
-               }
-       }
-
-       /* Copy 'other' sids.  We need to do sid filtering here to
-          prevent possible elevation of privileges.  See:
-
-           http://www.microsoft.com/windows2000/techinfo/administration/security/sidfilter.asp
-         */
-
-       for (i = 0; i < info3->num_other_sids; i++) 
-               sid_copy(&all_group_SIDs[
-                                n_lgroupSIDs + info3->num_groups2 + i],
-                        &info3->other_sids[i].sid);
-       
-       /* Where are the 'global' sids... */
-
-       /* can the user be guest? if yes, where is it stored? */
-       if (!NT_STATUS_IS_OK(
-                   nt_status = create_nt_user_token(
-                           &user_sid, &group_sid,
-                           n_lgroupSIDs + info3->num_groups2 + info3->num_other_sids, 
-                           all_group_SIDs, False, &token))) {
-               DEBUG(4,("create_nt_user_token failed\n"));
-               SAFE_FREE(all_group_SIDs);
-               return nt_status;
-       }
-
-       (*server_info)->ptok = token; 
-
-       SAFE_FREE(all_group_SIDs);
-       
-       return NT_STATUS_OK;
-}
-
 /***************************************************************************
  Free a user_info struct
 ***************************************************************************/
@@ -1102,7 +880,6 @@ void free_user_info(auth_usersupplied_info **user_info)
                SAFE_FREE((*user_info)->wksta_name.str);
                data_blob_free(&(*user_info)->lm_resp);
                data_blob_free(&(*user_info)->nt_resp);
-               SAFE_FREE((*user_info)->interactive_password);
                data_blob_clear_free(&(*user_info)->plaintext_password);
                ZERO_STRUCT(**user_info);
        }
diff --git a/source4/groupdb/mapping.c b/source4/groupdb/mapping.c
deleted file mode 100644 (file)
index 958d6de..0000000
+++ /dev/null
@@ -1,1340 +0,0 @@
-/* 
- *  Unix SMB/CIFS implementation.
- *  RPC Pipe client / server routines
- *  Copyright (C) Andrew Tridgell              1992-2000,
- *  Copyright (C) Jean François Micouleau      1998-2001.
- *  
- *  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
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *  
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *  
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "includes.h"
-
-static TDB_CONTEXT *tdb; /* used for driver files */
-
-#define DATABASE_VERSION_V1 1 /* native byte format. */
-#define DATABASE_VERSION_V2 2 /* le format. */
-
-#define GROUP_PREFIX "UNIXGROUP/"
-
-PRIVS privs[] = {
-       {SE_PRIV_NONE,           "no_privs",                  "No privilege"                    }, /* this one MUST be first */
-       {SE_PRIV_ADD_MACHINES,   "SeMachineAccountPrivilege", "Add workstations to the domain"  },
-       {SE_PRIV_SEC_PRIV,       "SeSecurityPrivilege",       "Manage the audit logs"           },
-       {SE_PRIV_TAKE_OWNER,     "SeTakeOwnershipPrivilege",  "Take ownership of file"          },
-       {SE_PRIV_ADD_USERS,      "SaAddUsers",                "Add users to the domain - Samba" },
-       {SE_PRIV_PRINT_OPERATOR, "SaPrintOp",                 "Add or remove printers - Samba"  },
-       {SE_PRIV_ALL,            "SaAllPrivs",                "all privileges"                  }
-};
-/*
-PRIVS privs[] = {
-       {  2, "SeCreateTokenPrivilege" },
-       {  3, "SeAssignPrimaryTokenPrivilege" },
-       {  4, "SeLockMemoryPrivilege" },
-       {  5, "SeIncreaseQuotaPrivilege" },
-       {  6, "SeMachineAccountPrivilege" },
-       {  7, "SeTcbPrivilege" },
-       {  8, "SeSecurityPrivilege" },
-       {  9, "SeTakeOwnershipPrivilege" },
-       { 10, "SeLoadDriverPrivilege" },
-       { 11, "SeSystemProfilePrivilege" },
-       { 12, "SeSystemtimePrivilege" },
-       { 13, "SeProfileSingleProcessPrivilege" },
-       { 14, "SeIncreaseBasePriorityPrivilege" },
-       { 15, "SeCreatePagefilePrivilege" },
-       { 16, "SeCreatePermanentPrivilege" },
-       { 17, "SeBackupPrivilege" },
-       { 18, "SeRestorePrivilege" },
-       { 19, "SeShutdownPrivilege" },
-       { 20, "SeDebugPrivilege" },
-       { 21, "SeAuditPrivilege" },
-       { 22, "SeSystemEnvironmentPrivilege" },
-       { 23, "SeChangeNotifyPrivilege" },
-       { 24, "SeRemoteShutdownPrivilege" },
-       { 25, "SeUndockPrivilege" },
-       { 26, "SeSyncAgentPrivilege" },
-       { 27, "SeEnableDelegationPrivilege" },
-};
-*/
-
-       /*
-        * Those are not really privileges like the other ones.
-        * They are handled in a special case and called
-        * system privileges.
-        *
-        * SeNetworkLogonRight
-        * SeUnsolicitedInputPrivilege
-        * SeBatchLogonRight
-        * SeServiceLogonRight
-        * SeInteractiveLogonRight
-        * SeDenyInteractiveLogonRight
-        * SeDenyNetworkLogonRight
-        * SeDenyBatchLogonRight
-        * SeDenyBatchLogonRight
-        */
-
-#if 0
-/****************************************************************************
-check if the user has the required privilege.
-****************************************************************************/
-static BOOL se_priv_access_check(NT_USER_TOKEN *token, uint32 privilege)
-{
-       /* no token, no privilege */
-       if (token==NULL)
-               return False;
-       
-       if ((token->privilege & privilege)==privilege)
-               return True;
-       
-       return False;
-}
-#endif
-
-/****************************************************************************
-dump the mapping group mapping to a text file
-****************************************************************************/
-char *decode_sid_name_use(fstring group, enum SID_NAME_USE name_use)
-{      
-       static fstring group_type;
-
-       switch(name_use) {
-               case SID_NAME_USER:
-                       fstrcpy(group_type,"User");
-                       break;
-               case SID_NAME_DOM_GRP:
-                       fstrcpy(group_type,"Domain group");
-                       break;
-               case SID_NAME_DOMAIN:
-                       fstrcpy(group_type,"Domain");
-                       break;
-               case SID_NAME_ALIAS:
-                       fstrcpy(group_type,"Local group");
-                       break;
-               case SID_NAME_WKN_GRP:
-                       fstrcpy(group_type,"Builtin group");
-                       break;
-               case SID_NAME_DELETED:
-                       fstrcpy(group_type,"Deleted");
-                       break;
-               case SID_NAME_INVALID:
-                       fstrcpy(group_type,"Invalid");
-                       break;
-               case SID_NAME_UNKNOWN:
-               default:
-                       fstrcpy(group_type,"Unknown type");
-                       break;
-       }
-       
-       fstrcpy(group, group_type);
-       return group_type;
-}
-
-/****************************************************************************
-initialise first time the mapping list - called from init_group_mapping()
-****************************************************************************/
-static BOOL default_group_mapping(void)
-{
-       DOM_SID sid_admins;
-       DOM_SID sid_users;
-       DOM_SID sid_guests;
-       fstring str_admins;
-       fstring str_users;
-       fstring str_guests;
-       LUID_ATTR set;
-
-       PRIVILEGE_SET privilege_none;
-       PRIVILEGE_SET privilege_all;
-       PRIVILEGE_SET privilege_print_op;
-
-       init_privilege(&privilege_none);
-       init_privilege(&privilege_all);
-       init_privilege(&privilege_print_op);
-
-       set.attr=0;
-       set.luid.high=0;
-       set.luid.low=SE_PRIV_PRINT_OPERATOR;
-       add_privilege(&privilege_print_op, set);
-
-       add_all_privilege(&privilege_all);
-
-       /* Add the Wellknown groups */
-
-       add_initial_entry(-1, "S-1-5-32-544", SID_NAME_ALIAS, "Administrators", "", privilege_all, PR_ACCESS_FROM_NETWORK|PR_LOG_ON_LOCALLY);
-       add_initial_entry(-1, "S-1-5-32-545", SID_NAME_ALIAS, "Users", "", privilege_none, PR_ACCESS_FROM_NETWORK|PR_LOG_ON_LOCALLY);
-       add_initial_entry(-1, "S-1-5-32-546", SID_NAME_ALIAS, "Guests", "", privilege_none, PR_ACCESS_FROM_NETWORK);
-       add_initial_entry(-1, "S-1-5-32-547", SID_NAME_ALIAS, "Power Users", "", privilege_none, PR_ACCESS_FROM_NETWORK|PR_LOG_ON_LOCALLY);
-
-       add_initial_entry(-1, "S-1-5-32-548", SID_NAME_ALIAS, "Account Operators", "", privilege_none, PR_ACCESS_FROM_NETWORK|PR_LOG_ON_LOCALLY);
-       add_initial_entry(-1, "S-1-5-32-549", SID_NAME_ALIAS, "System Operators", "", privilege_none, PR_ACCESS_FROM_NETWORK|PR_LOG_ON_LOCALLY);
-       add_initial_entry(-1, "S-1-5-32-550", SID_NAME_ALIAS, "Print Operators", "", privilege_print_op, PR_ACCESS_FROM_NETWORK|PR_LOG_ON_LOCALLY);
-       add_initial_entry(-1, "S-1-5-32-551", SID_NAME_ALIAS, "Backup Operators", "", privilege_none, PR_ACCESS_FROM_NETWORK|PR_LOG_ON_LOCALLY);
-
-       add_initial_entry(-1, "S-1-5-32-552", SID_NAME_ALIAS, "Replicators", "", privilege_none, PR_ACCESS_FROM_NETWORK);
-
-       /* Add the defaults domain groups */
-
-       sid_copy(&sid_admins, get_global_sam_sid());
-       sid_append_rid(&sid_admins, DOMAIN_GROUP_RID_ADMINS);
-       sid_to_string(str_admins, &sid_admins);
-       add_initial_entry(-1, str_admins, SID_NAME_DOM_GRP, "Domain Admins", "", privilege_all, PR_ACCESS_FROM_NETWORK|PR_LOG_ON_LOCALLY);
-
-       sid_copy(&sid_users,  get_global_sam_sid());
-       sid_append_rid(&sid_users,  DOMAIN_GROUP_RID_USERS);
-       sid_to_string(str_users, &sid_users);
-       add_initial_entry(-1, str_users,  SID_NAME_DOM_GRP, "Domain Users",  "", privilege_none, PR_ACCESS_FROM_NETWORK|PR_LOG_ON_LOCALLY);
-
-       sid_copy(&sid_guests, get_global_sam_sid());
-       sid_append_rid(&sid_guests, DOMAIN_GROUP_RID_GUESTS);
-       sid_to_string(str_guests, &sid_guests);
-       add_initial_entry(-1, str_guests, SID_NAME_DOM_GRP, "Domain Guests", "", privilege_none, PR_ACCESS_FROM_NETWORK);
-
-       return True;
-}
-
-/****************************************************************************
- Open the group mapping tdb.
-****************************************************************************/
-
-static BOOL init_group_mapping(void)
-{
-       static pid_t local_pid;
-       const char *vstring = "INFO/version";
-       int32 vers_id;
-       TALLOC_CTX *mem_ctx;
-       
-       if (tdb && local_pid == getpid())
-               return True;
-       mem_ctx = talloc_init("init_group_mapping");
-       if (!mem_ctx) {
-               DEBUG(0,("No memory to open group mapping database\n"));
-               return False;
-       }
-       tdb = tdb_open_log(lock_path(mem_ctx, "group_mapping.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
-       talloc_destroy(mem_ctx);
-       if (!tdb) {
-               DEBUG(0,("Failed to open group mapping database\n"));
-               return False;
-       }
-
-       local_pid = getpid();
-
-       /* handle a Samba upgrade */
-       tdb_lock_bystring(tdb, vstring, 0);
-
-       /* Cope with byte-reversed older versions of the db. */
-       vers_id = tdb_fetch_int32(tdb, vstring);
-       if ((vers_id == DATABASE_VERSION_V1) || (IREV(vers_id) == DATABASE_VERSION_V1)) {
-               /* Written on a bigendian machine with old fetch_int code. Save as le. */
-               tdb_store_int32(tdb, vstring, DATABASE_VERSION_V2);
-               vers_id = DATABASE_VERSION_V2;
-       }
-
-       if (vers_id != DATABASE_VERSION_V2) {
-               tdb_traverse(tdb, tdb_traverse_delete_fn, NULL);
-               tdb_store_int32(tdb, vstring, DATABASE_VERSION_V2);
-       }
-
-       tdb_unlock_bystring(tdb, vstring);
-
-       /* write a list of default groups */
-       if(!default_group_mapping())
-               return False;
-
-       return True;
-}
-
-/****************************************************************************
-****************************************************************************/
-BOOL add_mapping_entry(GROUP_MAP *map, int flag)
-{
-       TDB_DATA kbuf, dbuf;
-       pstring key, buf;
-       fstring string_sid="";
-       int len;
-       int i;
-       PRIVILEGE_SET *set;
-
-       if(!init_group_mapping()) {
-               DEBUG(0,("failed to initialize group mapping"));
-               return(False);
-       }
-       
-       sid_to_string(string_sid, &map->sid);
-
-       len = tdb_pack(buf, sizeof(buf), "ddffd",
-                       map->gid, map->sid_name_use, map->nt_name, map->comment, map->systemaccount);
-
-       /* write the privilege list in the TDB database */
-
-       set=&map->priv_set;
-       len += tdb_pack(buf+len, sizeof(buf)-len, "d", set->count);
-       for (i=0; i<set->count; i++)
-               len += tdb_pack(buf+len, sizeof(buf)-len, "ddd", 
-                               set->set[i].luid.low, set->set[i].luid.high, set->set[i].attr);
-
-       if (len > sizeof(buf))
-               return False;
-
-       slprintf(key, sizeof(key), "%s%s", GROUP_PREFIX, string_sid);
-
-       kbuf.dsize = strlen(key)+1;
-       kbuf.dptr = key;
-       dbuf.dsize = len;
-       dbuf.dptr = buf;
-       if (tdb_store(tdb, kbuf, dbuf, flag) != 0) return False;
-
-       return True;
-}
-
-/****************************************************************************
-initialise first time the mapping list
-****************************************************************************/
-BOOL add_initial_entry(gid_t gid, const char *sid, enum SID_NAME_USE sid_name_use,
-                      const char *nt_name, const char *comment, PRIVILEGE_SET priv_set, uint32 systemaccount)
-{
-       GROUP_MAP map;
-
-       if(!init_group_mapping()) {
-               DEBUG(0,("failed to initialize group mapping"));
-               return(False);
-       }
-       
-       map.gid=gid;
-       if (!string_to_sid(&map.sid, sid)) {
-               DEBUG(0, ("string_to_sid failed: %s", sid));
-               return False;
-       }
-       
-       map.sid_name_use=sid_name_use;
-       fstrcpy(map.nt_name, nt_name);
-       fstrcpy(map.comment, comment);
-       map.systemaccount=systemaccount;
-
-       map.priv_set.count=priv_set.count;
-       map.priv_set.set=priv_set.set;
-
-       pdb_add_group_mapping_entry(&map);
-
-       return True;
-}
-
-/****************************************************************************
-initialise a privilege list
-****************************************************************************/
-void init_privilege(PRIVILEGE_SET *priv_set)
-{
-       priv_set->count=0;
-       priv_set->control=0;
-       priv_set->set=NULL;
-}
-
-/****************************************************************************
-free a privilege list
-****************************************************************************/
-BOOL free_privilege(PRIVILEGE_SET *priv_set)
-{
-       if (priv_set->count==0) {
-               DEBUG(100,("free_privilege: count=0, nothing to clear ?\n"));
-               return False;
-       }
-
-       if (priv_set->set==NULL) {
-               DEBUG(0,("free_privilege: list ptr is NULL, very strange !\n"));
-               return False;
-       }
-
-       safe_free(priv_set->set);
-       priv_set->count=0;
-       priv_set->control=0;
-       priv_set->set=NULL;
-
-       return True;
-}
-
-/****************************************************************************
-add a privilege to a privilege array
-****************************************************************************/
-BOOL add_privilege(PRIVILEGE_SET *priv_set, LUID_ATTR set)
-{
-       LUID_ATTR *new_set;
-
-       /* check if the privilege is not already in the list */
-       if (check_priv_in_privilege(priv_set, set))
-               return False;
-
-       /* we can allocate memory to add the new privilege */
-
-       new_set=(LUID_ATTR *)Realloc(priv_set->set, (priv_set->count+1)*(sizeof(LUID_ATTR)));
-       if (new_set==NULL) {
-               DEBUG(0,("add_privilege: could not Realloc memory to add a new privilege\n"));
-               return False;
-       }
-
-       new_set[priv_set->count].luid.high=set.luid.high;
-       new_set[priv_set->count].luid.low=set.luid.low;
-       new_set[priv_set->count].attr=set.attr;
-       
-       priv_set->count++;
-       priv_set->set=new_set;
-       
-       return True;    
-}
-
-/****************************************************************************
-add all the privileges to a privilege array
-****************************************************************************/
-BOOL add_all_privilege(PRIVILEGE_SET *priv_set)
-{
-       LUID_ATTR set;
-
-       set.attr=0;
-       set.luid.high=0;
-       
-       set.luid.low=SE_PRIV_ADD_USERS;
-       add_privilege(priv_set, set);
-
-       set.luid.low=SE_PRIV_ADD_MACHINES;
-       add_privilege(priv_set, set);
-
-       set.luid.low=SE_PRIV_PRINT_OPERATOR;
-       add_privilege(priv_set, set);
-       
-       return True;
-}
-
-/****************************************************************************
-check if the privilege list is empty
-****************************************************************************/
-BOOL check_empty_privilege(PRIVILEGE_SET *priv_set)
-{
-       return (priv_set->count == 0);
-}
-
-/****************************************************************************
-check if the privilege is in the privilege list
-****************************************************************************/
-BOOL check_priv_in_privilege(PRIVILEGE_SET *priv_set, LUID_ATTR set)
-{
-       int i;
-
-       /* if the list is empty, obviously we can't have it */
-       if (check_empty_privilege(priv_set))
-               return False;
-
-       for (i=0; i<priv_set->count; i++) {
-               LUID_ATTR *cur_set;
-
-               cur_set=&priv_set->set[i];
-               /* check only the low and high part. Checking the attr field has no meaning */
-               if( (cur_set->luid.low==set.luid.low) && (cur_set->luid.high==set.luid.high) )
-                       return True;
-       }
-
-       return False;
-}
-
-/****************************************************************************
-remove a privilege from a privilege array
-****************************************************************************/
-BOOL remove_privilege(PRIVILEGE_SET *priv_set, LUID_ATTR set)
-{
-       LUID_ATTR *new_set;
-       LUID_ATTR *old_set;
-       int i,j;
-
-       /* check if the privilege is in the list */
-       if (!check_priv_in_privilege(priv_set, set))
-               return False;
-
-       /* special case if it's the only privilege in the list */
-       if (priv_set->count==1) {
-               free_privilege(priv_set);
-               init_privilege(priv_set);       
-       
-               return True;
-       }
-
-       /* 
-        * the privilege is there, create a new list,
-        * and copy the other privileges
-        */
-
-       old_set=priv_set->set;
-
-       new_set=(LUID_ATTR *)malloc((priv_set->count-1)*(sizeof(LUID_ATTR)));
-       if (new_set==NULL) {
-               DEBUG(0,("remove_privilege: could not malloc memory for new privilege list\n"));
-               return False;
-       }
-
-       for (i=0, j=0; i<priv_set->count; i++) {
-               if ((old_set[i].luid.low==set.luid.low) && 
-                   (old_set[i].luid.high==set.luid.high)) {
-                       continue;
-               }
-               
-               new_set[j].luid.low=old_set[i].luid.low;
-               new_set[j].luid.high=old_set[i].luid.high;
-               new_set[j].attr=old_set[i].attr;
-
-               j++;
-       }
-       
-       if (j!=priv_set->count-1) {
-               DEBUG(0,("remove_privilege: mismatch ! difference is not -1\n"));
-               DEBUGADD(0,("old count:%d, new count:%d\n", priv_set->count, j));
-               safe_free(new_set);
-               return False;
-       }
-               
-       /* ok everything is fine */
-       
-       priv_set->count--;
-       priv_set->set=new_set;
-       
-       safe_free(old_set);
-       
-       return True;    
-}
-
-/****************************************************************************
- Return the sid and the type of the unix group.
-****************************************************************************/
-
-BOOL get_group_map_from_sid(DOM_SID sid, GROUP_MAP *map, BOOL with_priv)
-{
-       TDB_DATA kbuf, dbuf;
-       pstring key;
-       fstring string_sid;
-       int ret;
-       int i;
-       PRIVILEGE_SET *set;
-       
-       if(!init_group_mapping()) {
-               DEBUG(0,("failed to initialize group mapping"));
-               return(False);
-       }
-
-       /* the key is the SID, retrieving is direct */
-
-       sid_to_string(string_sid, &sid);
-       slprintf(key, sizeof(key), "%s%s", GROUP_PREFIX, string_sid);
-
-       kbuf.dptr = key;
-       kbuf.dsize = strlen(key)+1;
-               
-       dbuf = tdb_fetch(tdb, kbuf);
-       if (!dbuf.dptr)
-               return False;
-
-       ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddffd",
-                               &map->gid, &map->sid_name_use, &map->nt_name, &map->comment, &map->systemaccount);
-
-       set=&map->priv_set;
-       init_privilege(set);
-       ret += tdb_unpack(dbuf.dptr+ret, dbuf.dsize-ret, "d", &set->count);
-
-       DEBUG(10,("get_group_map_from_sid: %d privileges\n", map->priv_set.count));
-
-       set->set = NULL;
-       if (set->count) {
-               set->set=(LUID_ATTR *)smb_xmalloc(set->count*sizeof(LUID_ATTR));
-       }
-
-       for (i=0; i<set->count; i++)
-               ret += tdb_unpack(dbuf.dptr+ret, dbuf.dsize-ret, "ddd", 
-                               &(set->set[i].luid.low), &(set->set[i].luid.high), &(set->set[i].attr));
-
-       SAFE_FREE(dbuf.dptr);
-       if (ret != dbuf.dsize) {
-               DEBUG(0,("get_group_map_from_sid: group mapping TDB corrupted ?\n"));
-               free_privilege(set);
-               return False;
-       }
-
-       /* we don't want the privileges */
-       if (with_priv==MAPPING_WITHOUT_PRIV)
-               free_privilege(set);
-
-       sid_copy(&map->sid, &sid);
-       
-       return True;
-}
-
-/****************************************************************************
- Return the sid and the type of the unix group.
-****************************************************************************/
-
-BOOL get_group_map_from_gid(gid_t gid, GROUP_MAP *map, BOOL with_priv)
-{
-       TDB_DATA kbuf, dbuf, newkey;
-       fstring string_sid;
-       int ret;
-       int i;
-       PRIVILEGE_SET *set;
-
-       if(!init_group_mapping()) {
-               DEBUG(0,("failed to initialize group mapping"));
-               return(False);
-       }
-
-       /* we need to enumerate the TDB to find the GID */
-
-       for (kbuf = tdb_firstkey(tdb); 
-            kbuf.dptr; 
-            newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
-
-               if (strncmp(kbuf.dptr, GROUP_PREFIX, strlen(GROUP_PREFIX)) != 0) continue;
-               
-               dbuf = tdb_fetch(tdb, kbuf);
-               if (!dbuf.dptr)
-                       continue;
-
-               fstrcpy(string_sid, kbuf.dptr+strlen(GROUP_PREFIX));
-
-               string_to_sid(&map->sid, string_sid);
-               
-               ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddffd",
-                                &map->gid, &map->sid_name_use, &map->nt_name, &map->comment, &map->systemaccount);
-
-               set=&map->priv_set;
-               ret += tdb_unpack(dbuf.dptr+ret, dbuf.dsize-ret, "d", &set->count);
-               set->set = NULL;
-               if (set->count) {
-                       set->set=(LUID_ATTR *)smb_xmalloc(set->count*sizeof(LUID_ATTR));
-               }
-
-               for (i=0; i<set->count; i++)
-                       ret += tdb_unpack(dbuf.dptr+ret, dbuf.dsize-ret, "ddd", 
-                                       &(set->set[i].luid.low), &(set->set[i].luid.high), &(set->set[i].attr));
-
-               SAFE_FREE(dbuf.dptr);
-               if (ret != dbuf.dsize){
-                       free_privilege(set);
-                       continue;
-               }
-
-               if (gid==map->gid) {
-                       if (!with_priv)
-                               free_privilege(&map->priv_set);
-                       return True;
-               }
-               
-               free_privilege(set);
-       }
-
-       return False;
-}
-
-/****************************************************************************
- Return the sid and the type of the unix group.
-****************************************************************************/
-
-BOOL get_group_map_from_ntname(char *name, GROUP_MAP *map, BOOL with_priv)
-{
-       TDB_DATA kbuf, dbuf, newkey;
-       fstring string_sid;
-       int ret;
-       int i;
-       PRIVILEGE_SET *set;
-
-       if(!init_group_mapping()) {
-               DEBUG(0,("get_group_map_from_ntname:failed to initialize group mapping"));
-               return(False);
-       }
-
-       /* we need to enumerate the TDB to find the name */
-
-       for (kbuf = tdb_firstkey(tdb); 
-            kbuf.dptr; 
-            newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
-
-               if (strncmp(kbuf.dptr, GROUP_PREFIX, strlen(GROUP_PREFIX)) != 0) continue;
-               
-               dbuf = tdb_fetch(tdb, kbuf);
-               if (!dbuf.dptr)
-                       continue;
-
-               fstrcpy(string_sid, kbuf.dptr+strlen(GROUP_PREFIX));
-
-               string_to_sid(&map->sid, string_sid);
-               
-               ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddffd",
-                                &map->gid, &map->sid_name_use, &map->nt_name, &map->comment, &map->systemaccount);
-
-               set=&map->priv_set;
-               ret += tdb_unpack(dbuf.dptr+ret, dbuf.dsize-ret, "d", &set->count);
-       
-               set->set=(LUID_ATTR *)malloc(set->count*sizeof(LUID_ATTR));
-               if (set->set==NULL) {
-                       DEBUG(0,("get_group_map_from_ntname: could not allocate memory for privileges\n"));
-                       return False;
-               }
-
-               for (i=0; i<set->count; i++)
-                       ret += tdb_unpack(dbuf.dptr+ret, dbuf.dsize-ret, "ddd", 
-                                       &(set->set[i].luid.low), &(set->set[i].luid.high), &(set->set[i].attr));
-
-               SAFE_FREE(dbuf.dptr);
-               if (ret != dbuf.dsize) {
-                       free_privilege(set);
-                       continue;
-               }
-
-               if (StrCaseCmp(name, map->nt_name)==0) {
-                       if (!with_priv)
-                               free_privilege(&map->priv_set);
-                       return True;
-               }
-
-               free_privilege(set);
-       }
-
-       return False;
-}
-
-/****************************************************************************
- Remove a group mapping entry.
-****************************************************************************/
-
-BOOL group_map_remove(DOM_SID sid)
-{
-       TDB_DATA kbuf, dbuf;
-       pstring key;
-       fstring string_sid;
-       
-       if(!init_group_mapping()) {
-               DEBUG(0,("failed to initialize group mapping"));
-               return(False);
-       }
-
-       /* the key is the SID, retrieving is direct */
-
-       sid_to_string(string_sid, &sid);
-       slprintf(key, sizeof(key), "%s%s", GROUP_PREFIX, string_sid);
-
-       kbuf.dptr = key;
-       kbuf.dsize = strlen(key)+1;
-               
-       dbuf = tdb_fetch(tdb, kbuf);
-       if (!dbuf.dptr)
-               return False;
-       
-       SAFE_FREE(dbuf.dptr);
-
-       if(tdb_delete(tdb, kbuf) != TDB_SUCCESS)
-               return False;
-
-       return True;
-}
-
-/****************************************************************************
- Enumerate the group mapping.
-****************************************************************************/
-
-BOOL enum_group_mapping(enum SID_NAME_USE sid_name_use, GROUP_MAP **rmap,
-                       int *num_entries, BOOL unix_only, BOOL with_priv)
-{
-       TDB_DATA kbuf, dbuf, newkey;
-       fstring string_sid;
-       fstring group_type;
-       GROUP_MAP map;
-       GROUP_MAP *mapt;
-       int ret;
-       int entries=0;
-       int i;
-       PRIVILEGE_SET *set;
-
-       if(!init_group_mapping()) {
-               DEBUG(0,("failed to initialize group mapping"));
-               return(False);
-       }
-
-       *num_entries=0;
-       *rmap=NULL;
-
-       for (kbuf = tdb_firstkey(tdb); 
-            kbuf.dptr; 
-            newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
-
-               if (strncmp(kbuf.dptr, GROUP_PREFIX, strlen(GROUP_PREFIX)) != 0)
-                       continue;
-               
-               dbuf = tdb_fetch(tdb, kbuf);
-               if (!dbuf.dptr)
-                       continue;
-
-               fstrcpy(string_sid, kbuf.dptr+strlen(GROUP_PREFIX));
-                               
-               ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddffd",
-                                &map.gid, &map.sid_name_use, &map.nt_name, &map.comment, &map.systemaccount);
-
-               set=&map.priv_set;
-               init_privilege(set);
-               
-               ret += tdb_unpack(dbuf.dptr+ret, dbuf.dsize-ret, "d", &set->count);
-       
-               if (set->count!=0) {
-                       set->set=(LUID_ATTR *)malloc(set->count*sizeof(LUID_ATTR));
-                       if (set->set==NULL) {
-                               DEBUG(0,("enum_group_mapping: could not allocate memory for privileges\n"));
-                               return False;
-                       }
-               }
-
-               for (i=0; i<set->count; i++)
-                       ret += tdb_unpack(dbuf.dptr+ret, dbuf.dsize-ret, "ddd", 
-                                       &(set->set[i].luid.low), &(set->set[i].luid.high), &(set->set[i].attr));
-
-               SAFE_FREE(dbuf.dptr);
-               if (ret != dbuf.dsize) {
-                       DEBUG(11,("enum_group_mapping: error in memory size\n"));
-                       free_privilege(set);
-                       continue;
-               }
-
-               /* list only the type or everything if UNKNOWN */
-               if (sid_name_use!=SID_NAME_UNKNOWN  && sid_name_use!=map.sid_name_use) {
-                       DEBUG(11,("enum_group_mapping: group %s is not of the requested type\n", map.nt_name));
-                       free_privilege(set);
-                       continue;
-               }
-               
-               if (unix_only==ENUM_ONLY_MAPPED && map.gid==-1) {
-                       DEBUG(11,("enum_group_mapping: group %s is non mapped\n", map.nt_name));
-                       free_privilege(set);
-                       continue;
-               }
-
-               string_to_sid(&map.sid, string_sid);
-               
-               decode_sid_name_use(group_type, map.sid_name_use);
-               DEBUG(11,("enum_group_mapping: returning group %s of type %s\n", map.nt_name ,group_type));
-
-               mapt=(GROUP_MAP *)Realloc((*rmap), (entries+1)*sizeof(GROUP_MAP));
-               if (!mapt) {
-                       DEBUG(0,("enum_group_mapping: Unable to enlarge group map!\n"));
-                       SAFE_FREE(*rmap);
-                       free_privilege(set);
-                       return False;
-               }
-               else
-                       (*rmap) = mapt;
-
-               mapt[entries].gid = map.gid;
-               sid_copy( &mapt[entries].sid, &map.sid);
-               mapt[entries].sid_name_use = map.sid_name_use;
-               fstrcpy(mapt[entries].nt_name, map.nt_name);
-               fstrcpy(mapt[entries].comment, map.comment);
-               mapt[entries].systemaccount=map.systemaccount;
-               mapt[entries].priv_set.count=set->count;
-               mapt[entries].priv_set.control=set->control;
-               mapt[entries].priv_set.set=set->set;
-               if (!with_priv)
-                       free_privilege(&(mapt[entries].priv_set));
-
-               entries++;
-       }
-
-       *num_entries=entries;
-
-       return True;
-}
-
-
-/****************************************************************************
-convert a privilege string to a privilege array
-****************************************************************************/
-void convert_priv_from_text(PRIVILEGE_SET *se_priv, char *privilege)
-{
-       pstring tok;
-       const char *p = privilege;
-       int i;
-       LUID_ATTR set;
-
-       /* By default no privilege */
-       init_privilege(se_priv);
-       
-       if (privilege==NULL)
-               return;
-
-       while(next_token(&p, tok, " ", sizeof(tok)) ) {
-               for (i=0; i<=PRIV_ALL_INDEX; i++) {
-                       if (StrCaseCmp(privs[i].priv, tok)==0) {
-                               set.attr=0;
-                               set.luid.high=0;
-                               set.luid.low=privs[i].se_priv;
-                               add_privilege(se_priv, set);
-                       }
-               }               
-       }
-}
-
-/****************************************************************************
-convert a privilege array to a privilege string
-****************************************************************************/
-void convert_priv_to_text(PRIVILEGE_SET *se_priv, char *privilege)
-{
-       int i,j;
-
-       if (privilege==NULL)
-               return;
-
-       ZERO_STRUCTP(privilege);
-
-       if (check_empty_privilege(se_priv)) {
-               fstrcat(privilege, "No privilege");
-               return;
-       }
-
-       for(i=0; i<se_priv->count; i++) {
-               j=1;
-               while (privs[j].se_priv!=se_priv->set[i].luid.low && j<=PRIV_ALL_INDEX) {
-                       j++;
-               }
-
-               fstrcat(privilege, privs[j].priv);
-               fstrcat(privilege, " ");
-       }
-}
-
-
-/*
- *
- * High level functions
- * better to use them than the lower ones.
- *
- * we are checking if the group is in the mapping file
- * and if the group is an existing unix group
- *
- */
-
-/* get a domain group from it's SID */
-
-BOOL get_domain_group_from_sid(DOM_SID sid, GROUP_MAP *map, BOOL with_priv)
-{
-       struct group *grp;
-
-       if(!init_group_mapping()) {
-               DEBUG(0,("failed to initialize group mapping"));
-               return(False);
-       }
-
-       DEBUG(10, ("get_domain_group_from_sid\n"));
-
-       /* if the group is NOT in the database, it CAN NOT be a domain group */
-       if(!pdb_getgrsid(map, sid, with_priv))
-               return False;
-
-       DEBUG(10, ("get_domain_group_from_sid: SID found in the TDB\n"));
-
-       /* if it's not a domain group, continue */
-       if (map->sid_name_use!=SID_NAME_DOM_GRP) {
-               if (with_priv)
-                       free_privilege(&map->priv_set);
-               return False;
-       }
-
-       DEBUG(10, ("get_domain_group_from_sid: SID is a domain group\n"));
-       
-       if (map->gid==-1) {
-               if (with_priv)
-                       free_privilege(&map->priv_set);
-               return False;
-       }
-
-       DEBUG(10, ("get_domain_group_from_sid: SID is mapped to gid:%d\n",map->gid));
-
-       if ( (grp=getgrgid(map->gid)) == NULL) {
-               DEBUG(10, ("get_domain_group_from_sid: gid DOESN'T exist in UNIX security\n"));
-               if (with_priv)
-                       free_privilege(&map->priv_set);
-               return False;
-       }
-
-       DEBUG(10, ("get_domain_group_from_sid: gid exists in UNIX security\n"));
-
-       return True;
-}
-
-
-/* get a local (alias) group from it's SID */
-
-BOOL get_local_group_from_sid(DOM_SID sid, GROUP_MAP *map, BOOL with_priv)
-{
-       struct group *grp;
-
-       if(!init_group_mapping()) {
-               DEBUG(0,("failed to initialize group mapping"));
-               return(False);
-       }
-
-       /* The group is in the mapping table */
-       if(pdb_getgrsid(map, sid, with_priv)) {
-               if (map->sid_name_use!=SID_NAME_ALIAS) {
-                       if (with_priv)
-                               free_privilege(&map->priv_set);
-                       return False;
-               }
-               
-               if (map->gid==-1) {
-                       if (with_priv)
-                               free_privilege(&map->priv_set);
-                       return False;
-               }
-
-               if ( (grp=getgrgid(map->gid)) == NULL) {
-                       if (with_priv)
-                               free_privilege(&map->priv_set);
-                       return False;
-               }
-       } else {
-               /* the group isn't in the mapping table.
-                * make one based on the unix information */
-               uint32 alias_rid;
-
-               sid_peek_rid(&sid, &alias_rid);
-               map->gid=pdb_group_rid_to_gid(alias_rid);
-
-               if ((grp=getgrgid(map->gid)) == NULL)
-                       return False;
-
-               map->sid_name_use=SID_NAME_ALIAS;
-               map->systemaccount=PR_ACCESS_FROM_NETWORK;
-
-               fstrcpy(map->nt_name, grp->gr_name);
-               fstrcpy(map->comment, "Local Unix Group");
-
-               init_privilege(&map->priv_set);
-
-               sid_copy(&map->sid, &sid);
-       }
-
-       return True;
-}
-
-/* get a builtin group from it's SID */
-
-BOOL get_builtin_group_from_sid(DOM_SID sid, GROUP_MAP *map, BOOL with_priv)
-{
-       struct group *grp;
-
-       if(!init_group_mapping()) {
-               DEBUG(0,("failed to initialize group mapping"));
-               return(False);
-       }
-
-       if(!pdb_getgrsid(map, sid, with_priv))
-               return False;
-
-       if (map->sid_name_use!=SID_NAME_WKN_GRP) {
-               if (with_priv)
-                       free_privilege(&map->priv_set);
-               return False;
-       }
-
-       if (map->gid==-1) {
-               if (with_priv)
-                       free_privilege(&map->priv_set);
-               return False;
-       }
-
-       if ( (grp=getgrgid(map->gid)) == NULL) {
-               if (with_priv)
-                       free_privilege(&map->priv_set);
-               return False;
-       }
-
-       return True;
-}
-
-
-
-/****************************************************************************
-Returns a GROUP_MAP struct based on the gid.
-****************************************************************************/
-BOOL get_group_from_gid(gid_t gid, GROUP_MAP *map, BOOL with_priv)
-{
-       struct group *grp;
-
-       if(!init_group_mapping()) {
-               DEBUG(0,("failed to initialize group mapping"));
-               return(False);
-       }
-
-       if ( (grp=getgrgid(gid)) == NULL)
-               return False;
-
-       /*
-        * make a group map from scratch if doesn't exist.
-        */
-       if (!pdb_getgrgid(map, gid, with_priv)) {
-               map->gid=gid;
-               map->sid_name_use=SID_NAME_ALIAS;
-               map->systemaccount=PR_ACCESS_FROM_NETWORK;
-               init_privilege(&map->priv_set);
-
-               /* interim solution until we have a last RID allocated */
-
-               sid_copy(&map->sid, get_global_sam_sid());
-               sid_append_rid(&map->sid, pdb_gid_to_group_rid(gid));
-
-               fstrcpy(map->nt_name, grp->gr_name);
-               fstrcpy(map->comment, "Local Unix Group");
-       }
-       
-       return True;
-}
-
-
-
-
-/****************************************************************************
- Get the member users of a group and
- all the users who have that group as primary.
-            
- give back an array of uid
- return the grand number of users
-
-
- TODO: sort the list and remove duplicate. JFM.
-
-****************************************************************************/
-        
-BOOL get_uid_list_of_group(gid_t gid, uid_t **uid, int *num_uids)
-{
-       struct group *grp;
-       struct passwd *pwd;
-       int i=0;
-       char *gr;
-       uid_t *u;
-       if(!init_group_mapping()) {
-               DEBUG(0,("failed to initialize group mapping"));
-               return(False);
-       }
-
-       *num_uids = 0;
-       *uid=NULL;
-       
-       if ( (grp=getgrgid(gid)) == NULL)
-               return False;
-
-       gr = grp->gr_mem[0];
-       DEBUG(10, ("getting members\n"));
-        
-       while (gr && (*gr != (char)'\0')) {
-               u = Realloc((*uid), sizeof(uid_t)*(*num_uids+1));
-               if (!u) {
-                       DEBUG(0,("get_uid_list_of_group: unable to enlarge uid list!\n"));
-                       return False;
-               }
-               else (*uid) = u;
-
-               if( (pwd=getpwnam_alloc(gr)) !=NULL) {
-                       (*uid)[*num_uids]=pwd->pw_uid;
-                       (*num_uids)++;
-               }
-               passwd_free(&pwd);
-               gr = grp->gr_mem[++i];
-       }
-       DEBUG(10, ("got [%d] members\n", *num_uids));
-
-       setpwent();
-       while ((pwd=getpwent()) != NULL) {
-               if (pwd->pw_gid==gid) {
-                       u = Realloc((*uid), sizeof(uid_t)*(*num_uids+1));
-                       if (!u) {
-                               DEBUG(0,("get_uid_list_of_group: unable to enlarge uid list!\n"));
-                               return False;
-                       }
-                       else (*uid) = u;
-                       (*uid)[*num_uids]=pwd->pw_uid;
-
-                       (*num_uids)++;
-               }
-       }
-       endpwent();
-       DEBUG(10, ("got primary groups, members: [%d]\n", *num_uids));
-
-        return True;
-}
-
-/****************************************************************************
- Create a UNIX group on demand.
-****************************************************************************/
-
-int smb_create_group(char *unix_group, gid_t *new_gid)
-{
-       pstring add_script;
-       int ret;
-       int fd = 0;
-
-       pstrcpy(add_script, lp_addgroup_script());
-       if (! *add_script) return -1;
-       pstring_sub(add_script, "%g", unix_group);
-       ret = smbrun(add_script, (new_gid!=NULL) ? &fd : NULL);
-       DEBUG(3,("smb_create_group: Running the command `%s' gave %d\n",add_script,ret));
-       if (ret != 0)
-               return ret;
-
-       if (fd != 0) {
-               fstring output;
-
-               *new_gid = 0;
-               if (read(fd, output, sizeof(output)) > 0) {
-                       *new_gid = (gid_t)strtoul(output, NULL, 10);
-               }
-               close(fd);
-
-               if (*new_gid == 0) {
-                       /* The output was garbage. We assume nobody
-                           will create group 0 via smbd. Now we try to
-                           get the group via getgrnam. */
-
-                       struct group *grp = getgrnam(unix_group);
-                       if (grp != NULL)
-                               *new_gid = grp->gr_gid;
-                       else
-                               return 1;
-               }
-       }
-
-       return ret;
-}
-
-/****************************************************************************
- Delete a UNIX group on demand.
-****************************************************************************/
-
-int smb_delete_group(char *unix_group)
-{
-       pstring del_script;
-       int ret;
-
-       pstrcpy(del_script, lp_delgroup_script());
-       if (! *del_script) return -1;
-       pstring_sub(del_script, "%g", unix_group);
-       ret = smbrun(del_script,NULL);
-       DEBUG(3,("smb_delete_group: Running the command `%s' gave %d\n",del_script,ret));
-       return ret;
-}
-
-/****************************************************************************
- Set a user's primary UNIX group.
-****************************************************************************/
-int smb_set_primary_group(const char *unix_group, const char* unix_user)
-{
-       pstring add_script;
-       int ret;
-
-       pstrcpy(add_script, lp_setprimarygroup_script());
-       if (! *add_script) return -1;
-       all_string_sub(add_script, "%g", unix_group, sizeof(add_script));
-       all_string_sub(add_script, "%u", unix_user, sizeof(add_script));
-       ret = smbrun(add_script,NULL);
-       DEBUG(3,("smb_set_primary_group: "
-                "Running the command `%s' gave %d\n",add_script,ret));
-       return ret;
-}
-
-/****************************************************************************
- Add a user to a UNIX group.
-****************************************************************************/
-
-int smb_add_user_group(char *unix_group, char *unix_user)
-{
-       pstring add_script;
-       int ret;
-
-       pstrcpy(add_script, lp_addusertogroup_script());
-       if (! *add_script) return -1;
-       pstring_sub(add_script, "%g", unix_group);
-       pstring_sub(add_script, "%u", unix_user);
-       ret = smbrun(add_script,NULL);
-       DEBUG(3,("smb_add_user_group: Running the command `%s' gave %d\n",add_script,ret));
-       return ret;
-}
-
-/****************************************************************************
- Delete a user from a UNIX group
-****************************************************************************/
-
-int smb_delete_user_group(const char *unix_group, const char *unix_user)
-{
-       pstring del_script;
-       int ret;
-
-       pstrcpy(del_script, lp_deluserfromgroup_script());
-       if (! *del_script) return -1;
-       pstring_sub(del_script, "%g", unix_group);
-       pstring_sub(del_script, "%u", unix_user);
-       ret = smbrun(del_script,NULL);
-       DEBUG(3,("smb_delete_user_group: Running the command `%s' gave %d\n",del_script,ret));
-       return ret;
-}
-
-
-NTSTATUS pdb_default_getgrsid(struct pdb_methods *methods, GROUP_MAP *map,
-                                DOM_SID sid, BOOL with_priv)
-{
-       return get_group_map_from_sid(sid, map, with_priv) ?
-               NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
-}
-
-NTSTATUS pdb_default_getgrgid(struct pdb_methods *methods, GROUP_MAP *map,
-                                gid_t gid, BOOL with_priv)
-{
-       return get_group_map_from_gid(gid, map, with_priv) ?
-               NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
-}
-
-NTSTATUS pdb_default_getgrnam(struct pdb_methods *methods, GROUP_MAP *map,
-                                char *name, BOOL with_priv)
-{
-       return get_group_map_from_ntname(name, map, with_priv) ?
-               NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
-}
-
-NTSTATUS pdb_default_add_group_mapping_entry(struct pdb_methods *methods,
-                                               GROUP_MAP *map)
-{
-       return add_mapping_entry(map, TDB_INSERT) ?
-               NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
-}
-
-NTSTATUS pdb_default_update_group_mapping_entry(struct pdb_methods *methods,
-                                                  GROUP_MAP *map)
-{
-       return add_mapping_entry(map, TDB_REPLACE) ?
-               NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
-}
-
-NTSTATUS pdb_default_delete_group_mapping_entry(struct pdb_methods *methods,
-                                                  DOM_SID sid)
-{
-       return group_map_remove(sid) ?
-               NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
-}
-
-NTSTATUS pdb_default_enum_group_mapping(struct pdb_methods *methods,
-                                          enum SID_NAME_USE sid_name_use,
-                                          GROUP_MAP **rmap, int *num_entries,
-                                          BOOL unix_only, BOOL with_priv)
-{
-       return enum_group_mapping(sid_name_use, rmap, num_entries, unix_only,
-                                 with_priv) ?
-               NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
-}
-
index e37f181082e2d152b85085b52c58c7e9cfb2c546..89e46e3782dd0da3b29c2e49deda7107ba3fb018 100644 (file)
@@ -34,12 +34,6 @@ typedef struct unicode_string
        uchar *unistr;
 } AUTH_UNISTR;
 
-typedef struct interactive_password
-{
-       OWF_INFO          lm_owf;              /* LM OWF Password */
-       OWF_INFO          nt_owf;              /* NT OWF Password */
-} auth_interactive_password;
-
 #define AUTH_FLAG_NONE        0x000000
 #define AUTH_FLAG_PLAINTEXT   0x000001
 #define AUTH_FLAG_LM_RESP     0x000002
@@ -51,7 +45,6 @@ typedef struct auth_usersupplied_info
        
        DATA_BLOB lm_resp;
        DATA_BLOB nt_resp;
-       auth_interactive_password * interactive_password;
        DATA_BLOB plaintext_password;
        
        BOOL encrypted;
index d4f2d28e6a11396bee624bfb2ac0dddf6e76a2ab..fd124034cf9707fc9a77ac9d63cfe1bfc591c672 100644 (file)
@@ -50,7 +50,6 @@ typedef struct _GROUP_MAP {
        fstring nt_name;
        fstring comment;
        uint32 systemaccount;
-       PRIVILEGE_SET priv_set;
 } GROUP_MAP;
 
 typedef struct _PRIVS {
index 6a8c6506509698b02ee026bf38dd61087e71d55f..405bcc0caa659b4bae49905f5f9b930fd8e812f8 100644 (file)
 #include "rpc_misc.h"  /* this only pulls in STRHDR */
 
 
-/* DCE/RPC packet types */
-
-enum RPC_PKT_TYPE
-{
-       RPC_REQUEST = 0x00,
-       RPC_RESPONSE = 0x02,
-       RPC_FAULT    = 0x03,
-       RPC_BIND     = 0x0B,
-       RPC_BINDACK  = 0x0C,
-       RPC_BINDNACK = 0x0D,
-       RPC_ALTCONT  = 0x0E,
-       RPC_ALTCONTRESP = 0x0F,
-       RPC_BINDRESP = 0x10 /* not the real name!  this is undocumented! */
-};
-
-/* DCE/RPC flags */
-#define RPC_FLG_FIRST 0x01
-#define RPC_FLG_LAST  0x02
-#define RPC_FLG_NOCALL 0x20
-
-#define SMBD_NTLMSSP_NEG_FLAGS 0x000082b1 /* ALWAYS_SIGN|NEG_NTLM|NEG_LM|NEG_SEAL|NEG_SIGN|NEG_UNICODE */
-
-/* NTLMSSP signature version */
-#define NTLMSSP_SIGN_VERSION 0x01
-
-/* NTLMSSP auth type and level. */
-#define NTLMSSP_AUTH_TYPE 0xa
-#define NTLMSSP_AUTH_LEVEL 0x6
-
-/* Maximum PDU fragment size. */
-#define MAX_PDU_FRAG_LEN 0x1630
-/* #define MAX_PDU_FRAG_LEN 0x10b8             this is what w2k sets */
-
-/*
- * Actual structure of a DCE UUID
- */
-
-typedef struct rpc_uuid
-{
-  uint32 time_low;
-  uint16 time_mid;
-  uint16 time_hi_and_version;
-  uint8 remaining[8];
-} RPC_UUID;
-
-#define RPC_UUID_LEN 16
-
-/* RPC_IFACE */
-typedef struct rpc_iface_info
-{
-  RPC_UUID uuid;    /* 16 bytes of rpc interface identification */
-  uint32 version;    /* the interface version number */
-
-} RPC_IFACE;
-
-#define RPC_IFACE_LEN (RPC_UUID_LEN + 4)
-
-struct pipe_id_info
-{
-       /* the names appear not to matter: the syntaxes _do_ matter */
-
-       const char *client_pipe;
-       RPC_IFACE abstr_syntax; /* this one is the abstract syntax id */
-
-       const char *server_pipe;  /* this one is the secondary syntax name */
-       RPC_IFACE trans_syntax; /* this one is the primary syntax id */
-};
-
-/* RPC_HDR - dce rpc header */
-typedef struct rpc_hdr_info
-{
-  uint8  major; /* 5 - RPC major version */
-  uint8  minor; /* 0 - RPC minor version */
-  uint8  pkt_type; /* RPC_PKT_TYPE - RPC response packet */
-  uint8  flags; /* DCE/RPC flags */
-  uint8  pack_type[4]; /* 0x1000 0000 - little-endian packed data representation */
-  uint16 frag_len; /* fragment length - data size (bytes) inc header and tail. */
-  uint16 auth_len; /* 0 - authentication length  */
-  uint32 call_id; /* call identifier.  matches 12th uint32 of incoming RPC data. */
-
-} RPC_HDR;
-
-#define RPC_HEADER_LEN 16
-
-/* RPC_HDR_REQ - ms request rpc header */
-typedef struct rpc_hdr_req_info
-{
-  uint32 alloc_hint;   /* allocation hint - data size (bytes) minus header and tail. */
-  uint16 context_id;   /* 0 - presentation context identifier */
-  uint16  opnum;        /* opnum */
-
-} RPC_HDR_REQ;
-
-#define RPC_HDR_REQ_LEN 8
-
-/* RPC_HDR_RESP - ms response rpc header */
-typedef struct rpc_hdr_resp_info
-{
-  uint32 alloc_hint;   /* allocation hint - data size (bytes) minus header and tail. */
-  uint16 context_id;   /* 0 - presentation context identifier */
-  uint8  cancel_count; /* 0 - cancel count */
-  uint8  reserved;     /* 0 - reserved. */
-
-} RPC_HDR_RESP;
-
-#define RPC_HDR_RESP_LEN 8
-
-/* RPC_HDR_FAULT - fault rpc header */
-typedef struct rpc_hdr_fault_info
-{
-  NTSTATUS status;
-  uint32 reserved; /* 0x0000 0000 */
-} RPC_HDR_FAULT;
-
-#define RPC_HDR_FAULT_LEN 8
-
-/* this seems to be the same string name depending on the name of the pipe,
- * but is more likely to be linked to the interface name
- * "srvsvc", "\\PIPE\\ntsvcs"
- * "samr", "\\PIPE\\lsass"
- * "wkssvc", "\\PIPE\\wksvcs"
- * "NETLOGON", "\\PIPE\\NETLOGON"
- */
-/* RPC_ADDR_STR */
-typedef struct rpc_addr_info
-{
-  uint16 len;   /* length of the string including null terminator */
-  fstring str; /* the string above in single byte, null terminated form */
-
-} RPC_ADDR_STR;
-
-/* RPC_HDR_BBA */
-typedef struct rpc_hdr_bba_info
-{
-  uint16 max_tsize;       /* maximum transmission fragment size (0x1630) */
-  uint16 max_rsize;       /* max receive fragment size (0x1630) */
-  uint32 assoc_gid;       /* associated group id (0x0) */
-
-} RPC_HDR_BBA;
-
-#define RPC_HDR_BBA_LEN 8
-
-/* RPC_HDR_AUTHA */
-typedef struct rpc_hdr_autha_info
-{
-       uint16 max_tsize;       /* maximum transmission fragment size (0x1630) */
-       uint16 max_rsize;       /* max receive fragment size (0x1630) */
-
-       uint8 auth_type; /* 0x0a */
-       uint8 auth_level; /* 0x06 */
-       uint8 stub_type_len; /* don't know */
-       uint8 padding; /* padding */
-
-       uint32 unknown; /* 0x0014a0c0 */
-
-} RPC_HDR_AUTHA;
-
-#define RPC_HDR_AUTHA_LEN 12
-
-/* RPC_HDR_AUTH */
-typedef struct rpc_hdr_auth_info
-{
-       uint8 auth_type; /* 0x0a */
-       uint8 auth_level; /* 0x06 */
-       uint8 stub_type_len; /* don't know */
-       uint8 padding; /* padding */
-
-       uint32 unknown; /* pointer */
-
-} RPC_HDR_AUTH;
-
-#define RPC_HDR_AUTH_LEN 8
-
-/* RPC_BIND_REQ - ms req bind */
-typedef struct rpc_bind_req_info
-{
-  RPC_HDR_BBA bba;
-
-  uint32 num_elements;    /* the number of elements (0x1) */
-  uint16 context_id;      /* presentation context identifier (0x0) */
-  uint8 num_syntaxes;     /* the number of syntaxes (has always been 1?)(0x1) */
-
-  RPC_IFACE abstract;     /* num and vers. of interface client is using */
-  RPC_IFACE transfer;     /* num and vers. of interface to use for replies */
-  
-} RPC_HDR_RB;
-
-/* 
- * The following length is 8 bytes RPC_HDR_BBA_LEN, 8 bytes internals 
- * (with 3 bytes padding), + 2 x RPC_IFACE_LEN bytes for RPC_IFACE structs.
- */
-
-#define RPC_HDR_RB_LEN (RPC_HDR_BBA_LEN + 8 + (2*RPC_IFACE_LEN))
-
-/* RPC_RESULTS - can only cope with one reason, right now... */
-typedef struct rpc_results_info
-{
-/* uint8[] # 4-byte alignment padding, against SMB header */
-
-  uint8 num_results; /* the number of results (0x01) */
-
-/* uint8[] # 4-byte alignment padding, against SMB header */
-
-  uint16 result; /* result (0x00 = accept) */
-  uint16 reason; /* reason (0x00 = no reason specified) */
-
-} RPC_RESULTS;
-
-/* RPC_HDR_BA */
-typedef struct rpc_hdr_ba_info
-{
-  RPC_HDR_BBA bba;
-
-  RPC_ADDR_STR addr    ;  /* the secondary address string, as described earlier */
-  RPC_RESULTS  res     ; /* results and reasons */
-  RPC_IFACE    transfer; /* the transfer syntax from the request */
-
-} RPC_HDR_BA;
-
-/* RPC_AUTH_VERIFIER */
-typedef struct rpc_auth_verif_info
-{
-       fstring signature; /* "NTLMSSP" */
-       uint32  msg_type; /* NTLMSSP_MESSAGE_TYPE (1,2,3) */
-
-} RPC_AUTH_VERIFIER;
-
-/* this is TEMPORARILY coded up as a specific structure */
-/* this structure comes after the bind request */
-/* RPC_AUTH_NTLMSSP_NEG */
-typedef struct rpc_auth_ntlmssp_neg_info
-{
-       uint32  neg_flgs; /* 0x0000 b2b3 */
-
-       STRHDR hdr_myname; /* offset is against START of this structure */
-       STRHDR hdr_domain; /* offset is against START of this structure */
-
-       fstring myname; /* calling workstation's name */
-       fstring domain; /* calling workstations's domain */
-
-} RPC_AUTH_NTLMSSP_NEG;
-
-/* this is TEMPORARILY coded up as a specific structure */
-/* this structure comes after the bind acknowledgement */
-/* RPC_AUTH_NTLMSSP_CHAL */
-typedef struct rpc_auth_ntlmssp_chal_info
-{
-       uint32 unknown_1; /* 0x0000 0000 */
-       uint32 unknown_2; /* 0x0000 0028 */
-       uint32 neg_flags; /* 0x0000 82b1 */
-
-       uint8 challenge[8]; /* ntlm challenge */
-       uint8 reserved [8]; /* zeros */
-
-} RPC_AUTH_NTLMSSP_CHAL;
-
-
-/* RPC_AUTH_NTLMSSP_RESP */
-typedef struct rpc_auth_ntlmssp_resp_info
-{
-       STRHDR hdr_lm_resp; /* 24 byte response */
-       STRHDR hdr_nt_resp; /* 24 byte response */
-       STRHDR hdr_domain;
-       STRHDR hdr_usr;
-       STRHDR hdr_wks;
-       STRHDR hdr_sess_key; /* NULL unless negotiated */
-       uint32 neg_flags; /* 0x0000 82b1 */
-
-       fstring sess_key;
-       fstring wks;
-       fstring user;
-       fstring domain;
-       fstring nt_resp;
-       fstring lm_resp;
-
-} RPC_AUTH_NTLMSSP_RESP;
-
-/* attached to the end of encrypted rpc requests and responses */
-/* RPC_AUTH_NTLMSSP_CHK */
-typedef struct rpc_auth_ntlmssp_chk_info
-{
-       uint32 ver; /* 0x0000 0001 */
-       uint32 reserved;
-       uint32 crc32; /* checksum using 0xEDB8 8320 as a polynomial */
-       uint32 seq_num;
-
-} RPC_AUTH_NTLMSSP_CHK;
-
-#define RPC_AUTH_NTLMSSP_CHK_LEN 16
 
 
 #endif /* _DCE_RPC_H */
index c091e7332127cb94eff6808d55ec944195685246..d4040af3aa943988a949c841aa0414867676cb6a 100644 (file)
 /* XXXX these are here to get a compile! */
 #define LSA_LOOKUPRIDS      0xFD
 
-/* DOM_QUERY - info class 3 and 5 LSA Query response */
-typedef struct dom_query_info
-{
-  uint16 uni_dom_max_len; /* domain name string length * 2 */
-  uint16 uni_dom_str_len; /* domain name string length * 2 */
-  uint32 buffer_dom_name; /* undocumented domain name string buffer pointer */
-  uint32 buffer_dom_sid; /* undocumented domain SID string buffer pointer */
-  UNISTR2 uni_domain_name; /* domain name (unicode string) */
-  DOM_SID2 dom_sid; /* domain SID */
-
-} DOM_QUERY;
-
-/* level 5 is same as level 3. */
-typedef DOM_QUERY DOM_QUERY_3;
-typedef DOM_QUERY DOM_QUERY_5;
-
-/* level 2 is auditing settings */
-typedef struct dom_query_2
-{
-       uint32 auditing_enabled;
-       uint32 count1; /* usualy 7, at least on nt4sp4 */
-       uint32 count2; /* the same */
-       uint32 *auditsettings;
-} DOM_QUERY_2;
-
-/* level 6 is server role information */
-typedef struct dom_query_6
-{
-       uint16 server_role; /* 2=backup, 3=primary */
-} DOM_QUERY_6;
-
 typedef struct seq_qos_info
 {
        uint32 len; /* 12 */
@@ -141,34 +110,6 @@ typedef struct lsa_q_open_pol_info
 
 } LSA_Q_OPEN_POL;
 
-/* LSA_R_OPEN_POL - response to LSA Open Policy */
-typedef struct lsa_r_open_pol_info
-{
-       POLICY_HND pol; /* policy handle */
-       NTSTATUS status; /* return code */
-
-} LSA_R_OPEN_POL;
-
-/* LSA_Q_OPEN_POL2 - LSA Query Open Policy */
-typedef struct lsa_q_open_pol2_info
-{
-       uint32       ptr;             /* undocumented buffer pointer */
-       UNISTR2      uni_server_name; /* server name, starting with two '\'s */
-       LSA_OBJ_ATTR attr           ; /* object attributes */
-
-       uint32 des_access; /* desired access attributes */
-
-} LSA_Q_OPEN_POL2;
-
-/* LSA_R_OPEN_POL2 - response to LSA Open Policy */
-typedef struct lsa_r_open_pol2_info
-{
-       POLICY_HND pol; /* policy handle */
-       NTSTATUS status; /* return code */
-
-} LSA_R_OPEN_POL2;
-
-
 #define POLICY_VIEW_LOCAL_INFORMATION    0x00000001
 #define POLICY_VIEW_AUDIT_INFORMATION    0x00000002
 #define POLICY_GET_PRIVATE_INFORMATION   0x00000004
@@ -215,546 +156,6 @@ typedef struct lsa_r_open_pol2_info
                             POLICY_VIEW_LOCAL_INFORMATION    |\
                             POLICY_LOOKUP_NAMES )
 
-/* LSA_Q_QUERY_SEC_OBJ - LSA query security */
-typedef struct lsa_query_sec_obj_info
-{
-       POLICY_HND pol; /* policy handle */
-       uint32 sec_info;
-
-} LSA_Q_QUERY_SEC_OBJ;
-
-/* LSA_R_QUERY_SEC_OBJ - probably an open */
-typedef struct r_lsa_query_sec_obj_info
-{
-       uint32 ptr;
-       SEC_DESC_BUF *buf;
-
-       NTSTATUS status;         /* return status */
-
-} LSA_R_QUERY_SEC_OBJ;
-
-/* LSA_Q_QUERY_INFO - LSA query info policy */
-typedef struct lsa_query_info
-{
-       POLICY_HND pol; /* policy handle */
-    uint16 info_class; /* info class */
-
-} LSA_Q_QUERY_INFO;
-
-/* LSA_INFO_UNION */
-typedef union lsa_info_union
-{
-       DOM_QUERY_2 id2;
-       DOM_QUERY_3 id3;
-       DOM_QUERY_5 id5;
-       DOM_QUERY_6 id6;
-} LSA_INFO_UNION;
-
-/* LSA_R_QUERY_INFO - response to LSA query info policy */
-typedef struct lsa_r_query_info
-{
-    uint32 undoc_buffer; /* undocumented buffer pointer */
-    uint16 info_class; /* info class (same as info class in request) */
-   
-       LSA_INFO_UNION dom; 
-
-       NTSTATUS status; /* return code */
-
-} LSA_R_QUERY_INFO;
-
-/* LSA_DNS_DOM_INFO - DNS domain info - info class 12*/
-typedef struct lsa_dns_dom_info
-{
-       UNIHDR  hdr_nb_dom_name; /* netbios domain name */
-       UNIHDR  hdr_dns_dom_name;
-       UNIHDR  hdr_forest_name;
-
-       GUID       dom_guid; /* domain GUID */
-
-       UNISTR2 uni_nb_dom_name;
-       UNISTR2 uni_dns_dom_name;
-       UNISTR2 uni_forest_name;
-
-       uint32 ptr_dom_sid;
-       DOM_SID2   dom_sid; /* domain SID */
-} LSA_DNS_DOM_INFO;
-
-typedef union lsa_info2_union
-{
-       LSA_DNS_DOM_INFO dns_dom_info;
-} LSA_INFO2_UNION;
-
-/* LSA_Q_QUERY_INFO2 - LSA query info */
-typedef struct lsa_q_query_info2
-{
-       POLICY_HND pol;    /* policy handle */
-       uint16 info_class; /* info class */
-} LSA_Q_QUERY_INFO2;
-
-typedef struct lsa_r_query_info2
-{
-       uint32 ptr;    /* pointer to info struct */
-       uint16 info_class;
-       LSA_INFO2_UNION info; /* so far the only one */
-       NTSTATUS status;
-} LSA_R_QUERY_INFO2;
-
-/* LSA_Q_ENUM_TRUST_DOM - LSA enumerate trusted domains */
-typedef struct lsa_enum_trust_dom_info
-{
-       POLICY_HND pol; /* policy handle */
-       uint32 enum_context; /* enumeration context handle */
-       uint32 preferred_len; /* preferred maximum length */
-
-} LSA_Q_ENUM_TRUST_DOM;
-
-/* LSA_R_ENUM_TRUST_DOM - response to LSA enumerate trusted domains */
-typedef struct lsa_r_enum_trust_dom_info
-{
-       uint32 enum_context; /* enumeration context handle */
-       uint32 num_domains; /* number of domains */
-       uint32 ptr_enum_domains; /* buffer pointer to num domains */
-
-       /* this lot is only added if ptr_enum_domains is non-NULL */
-       uint32 num_domains2; /* number of domains */
-       UNIHDR2 *hdr_domain_name;
-       UNISTR2 *uni_domain_name;
-       DOM_SID2 *domain_sid;
-
-       NTSTATUS status; /* return code */
-
-} LSA_R_ENUM_TRUST_DOM;
-
-/* LSA_Q_CLOSE */
-typedef struct lsa_q_close_info
-{
-       POLICY_HND pol; /* policy handle */
-
-} LSA_Q_CLOSE;
-
-/* LSA_R_CLOSE */
-typedef struct lsa_r_close_info
-{
-       POLICY_HND pol; /* policy handle.  should be all zeros. */
-
-       NTSTATUS status; /* return code */
-
-} LSA_R_CLOSE;
-
-
-#define MAX_REF_DOMAINS 32
-
-/* DOM_TRUST_HDR */
-typedef struct dom_trust_hdr
-{
-       UNIHDR hdr_dom_name; /* referenced domain unicode string headers */
-       uint32 ptr_dom_sid;
-
-} DOM_TRUST_HDR;
-       
-/* DOM_TRUST_INFO */
-typedef struct dom_trust_info
-{
-       UNISTR2  uni_dom_name; /* domain name unicode string */
-       DOM_SID2 ref_dom     ; /* referenced domain SID */
-
-} DOM_TRUST_INFO;
-       
-/* DOM_R_REF */
-typedef struct dom_ref_info
-{
-    uint32 num_ref_doms_1; /* num referenced domains */
-    uint32 ptr_ref_dom; /* pointer to referenced domains */
-    uint32 max_entries; /* 32 - max number of entries */
-    uint32 num_ref_doms_2; /* num referenced domains */
-
-    DOM_TRUST_HDR  hdr_ref_dom[MAX_REF_DOMAINS]; /* referenced domains */
-    DOM_TRUST_INFO ref_dom    [MAX_REF_DOMAINS]; /* referenced domains */
-
-} DOM_R_REF;
-
-/* the domain_idx points to a SID associated with the name */
-
-/* LSA_TRANS_NAME - translated name */
-typedef struct lsa_trans_name_info
-{
-       uint16 sid_name_use; /* value is 5 for a well-known group; 2 for a domain group; 1 for a user... */
-       UNIHDR hdr_name; 
-       uint32 domain_idx; /* index into DOM_R_REF array of SIDs */
-
-} LSA_TRANS_NAME;
-
-/* This number purly arbitary - just to prevent a client from requesting large amounts of memory */
-#define MAX_LOOKUP_SIDS 256
-
-/* LSA_TRANS_NAME_ENUM - LSA Translated Name Enumeration container */
-typedef struct lsa_trans_name_enum_info
-{
-       uint32 num_entries;
-       uint32 ptr_trans_names;
-       uint32 num_entries2;
-       
-       LSA_TRANS_NAME *name; /* translated names  */
-       UNISTR2 *uni_name;
-
-} LSA_TRANS_NAME_ENUM;
-
-/* LSA_SID_ENUM - LSA SID enumeration container */
-typedef struct lsa_sid_enum_info
-{
-       uint32 num_entries;
-       uint32 ptr_sid_enum;
-       uint32 num_entries2;
-       
-       uint32 *ptr_sid; /* domain SID pointers to be looked up. */
-       DOM_SID2 *sid; /* domain SIDs to be looked up. */
-
-} LSA_SID_ENUM;
-
-/* LSA_Q_LOOKUP_SIDS - LSA Lookup SIDs */
-typedef struct lsa_q_lookup_sids
-{
-       POLICY_HND          pol; /* policy handle */
-       LSA_SID_ENUM        sids;
-       LSA_TRANS_NAME_ENUM names;
-       LOOKUP_LEVEL        level;
-       uint32              mapped_count;
-
-} LSA_Q_LOOKUP_SIDS;
-
-/* LSA_R_LOOKUP_SIDS - response to LSA Lookup SIDs */
-typedef struct lsa_r_lookup_sids
-{
-       uint32              ptr_dom_ref;
-       DOM_R_REF           *dom_ref; /* domain reference info */
-
-       LSA_TRANS_NAME_ENUM *names;
-       uint32              mapped_count;
-
-       NTSTATUS            status; /* return code */
-
-} LSA_R_LOOKUP_SIDS;
-
-/* LSA_Q_LOOKUP_NAMES - LSA Lookup NAMEs */
-typedef struct lsa_q_lookup_names
-{
-       POLICY_HND pol; /* policy handle */
-       uint32 num_entries;
-       uint32 num_entries2;
-       UNIHDR  *hdr_name; /* name buffer pointers */
-       UNISTR2 *uni_name; /* names to be looked up */
-
-       uint32 num_trans_entries;
-       uint32 ptr_trans_sids; /* undocumented domain SID buffer pointer */
-       uint32 lookup_level;
-       uint32 mapped_count;
-
-} LSA_Q_LOOKUP_NAMES;
-
-/* LSA_R_LOOKUP_NAMES - response to LSA Lookup NAMEs by name */
-typedef struct lsa_r_lookup_names
-{
-       uint32 ptr_dom_ref;
-       DOM_R_REF *dom_ref; /* domain reference info */
-
-       uint32 num_entries;
-       uint32 ptr_entries;
-       uint32 num_entries2;
-       DOM_RID2 *dom_rid; /* domain RIDs being looked up */
-
-       uint32 mapped_count;
-
-       NTSTATUS status; /* return code */
-} LSA_R_LOOKUP_NAMES;
-
-/* This is probably a policy handle but at the moment we
-   never read it - so use a dummy struct. */
-
-typedef struct lsa_q_open_secret
-{
-       uint32 dummy;
-} LSA_Q_OPEN_SECRET;
-
-/* We always return "not found" at present - so just marshal the minimum. */
-
-typedef struct lsa_r_open_secret
-{
-       uint32 dummy1;
-       uint32 dummy2;
-       uint32 dummy3;
-       uint32 dummy4;
-       NTSTATUS status;
-} LSA_R_OPEN_SECRET;
-
-typedef struct lsa_enum_priv_entry
-{
-       UNIHDR hdr_name;
-       uint32 luid_low;
-       uint32 luid_high;
-       UNISTR2 name;
-       
-} LSA_PRIV_ENTRY;
-
-/* LSA_Q_ENUM_PRIVS - LSA enum privileges */
-typedef struct lsa_q_enum_privs
-{
-       POLICY_HND pol; /* policy handle */
-       uint32 enum_context;
-       uint32 pref_max_length;
-} LSA_Q_ENUM_PRIVS;
-
-typedef struct lsa_r_enum_privs
-{
-       uint32 enum_context;
-       uint32 count;
-       uint32 ptr;
-       uint32 count1;
-
-       LSA_PRIV_ENTRY *privs;
-
-       NTSTATUS status;
-} LSA_R_ENUM_PRIVS;
-
-/* LSA_Q_ENUM_ACCT_RIGHTS - LSA enum account rights */
-typedef struct
-{
-       POLICY_HND pol; /* policy handle */
-       DOM_SID2 sid;
-} LSA_Q_ENUM_ACCT_RIGHTS;
-
-/* LSA_R_ENUM_ACCT_RIGHTS - LSA enum account rights */
-typedef struct
-{
-       uint32 count;
-       UNISTR2_ARRAY rights;
-       NTSTATUS status;
-} LSA_R_ENUM_ACCT_RIGHTS;
-
-
-/* LSA_Q_ADD_ACCT_RIGHTS - LSA add account rights */
-typedef struct
-{
-       POLICY_HND pol; /* policy handle */
-       DOM_SID2 sid;
-       UNISTR2_ARRAY rights;
-} LSA_Q_ADD_ACCT_RIGHTS;
-
-/* LSA_R_ADD_ACCT_RIGHTS - LSA add account rights */
-typedef struct
-{
-       NTSTATUS status;
-} LSA_R_ADD_ACCT_RIGHTS;
-
-
-/* LSA_Q_REMOVE_ACCT_RIGHTS - LSA remove account rights */
-typedef struct
-{
-       POLICY_HND pol; /* policy handle */
-       DOM_SID2 sid;
-       uint32 removeall;
-       UNISTR2_ARRAY rights;
-} LSA_Q_REMOVE_ACCT_RIGHTS;
-
-/* LSA_R_REMOVE_ACCT_RIGHTS - LSA remove account rights */
-typedef struct
-{
-       NTSTATUS status;
-} LSA_R_REMOVE_ACCT_RIGHTS;
-
-/* LSA_Q_ENUM_ACCT_WITH_RIGHT - LSA enum accounts with right */
-typedef struct
-{
-       POLICY_HND pol;
-       STRHDR right_hdr;
-       UNISTR2 right; 
-} LSA_Q_ENUM_ACCT_WITH_RIGHT;
-
-/* LSA_R_ENUM_ACCT_WITH_RIGHT - LSA enum accounts with right */
-typedef struct
-{
-       uint32 count;
-       SID_ARRAY sids;
-       NTSTATUS status;
-} LSA_R_ENUM_ACCT_WITH_RIGHT;
-
-
-/* LSA_Q_PRIV_GET_DISPNAME - LSA get privilege display name */
-typedef struct lsa_q_priv_get_dispname
-{
-       POLICY_HND pol; /* policy handle */
-       UNIHDR hdr_name;
-       UNISTR2 name;
-       uint16 lang_id;
-       uint16 lang_id_sys;
-} LSA_Q_PRIV_GET_DISPNAME;
-
-typedef struct lsa_r_priv_get_dispname
-{
-       uint32 ptr_info;
-       UNIHDR hdr_desc;
-       UNISTR2 desc;
-       /* Don't align ! */
-       uint16 lang_id;
-       /* align */
-       NTSTATUS status;
-} LSA_R_PRIV_GET_DISPNAME;
-
-/* LSA_Q_ENUM_ACCOUNTS */
-typedef struct lsa_q_enum_accounts
-{
-       POLICY_HND pol; /* policy handle */
-       uint32 enum_context;
-       uint32 pref_max_length;
-} LSA_Q_ENUM_ACCOUNTS;
-
-/* LSA_R_ENUM_ACCOUNTS */
-typedef struct lsa_r_enum_accounts
-{
-       uint32 enum_context;
-       LSA_SID_ENUM sids;
-       NTSTATUS status;
-} LSA_R_ENUM_ACCOUNTS;
-
-/* LSA_Q_UNK_GET_CONNUSER - gets username\domain of connected user
-                  called when "Take Ownership" is clicked -SK */
-typedef struct lsa_q_unk_get_connuser
-{
-  uint32 ptr_srvname;
-  UNISTR2 uni2_srvname;
-  uint32 unk1; /* 3 unknown uint32's are seen right after uni2_srvname */
-  uint32 unk2; /* unk2 appears to be a ptr, unk1 = unk3 = 0 usually */
-  uint32 unk3; 
-} LSA_Q_UNK_GET_CONNUSER;
-
-/* LSA_R_UNK_GET_CONNUSER */
-typedef struct lsa_r_unk_get_connuser
-{
-  uint32 ptr_user_name;
-  UNIHDR hdr_user_name;
-  UNISTR2 uni2_user_name;
-  
-  uint32 unk1;
-  
-  uint32 ptr_dom_name;
-  UNIHDR hdr_dom_name;
-  UNISTR2 uni2_dom_name;
-
-  NTSTATUS status;
-} LSA_R_UNK_GET_CONNUSER;
-
-
-typedef struct lsa_q_openaccount
-{
-       POLICY_HND pol; /* policy handle */
-       DOM_SID2 sid;
-       uint32 access; /* desired access */
-} LSA_Q_OPENACCOUNT;
-
-typedef struct lsa_r_openaccount
-{
-       POLICY_HND pol; /* policy handle */
-       NTSTATUS status;
-} LSA_R_OPENACCOUNT;
-
-typedef struct lsa_q_enumprivsaccount
-{
-       POLICY_HND pol; /* policy handle */
-} LSA_Q_ENUMPRIVSACCOUNT;
-
-
-typedef struct LUID
-{
-       uint32 low;
-       uint32 high;
-} LUID;
-
-typedef struct LUID_ATTR
-{
-       LUID luid;
-       uint32 attr;
-} LUID_ATTR ;
-
-typedef struct privilege_set
-{
-       uint32 count;
-       uint32 control;
-       LUID_ATTR *set;
-} PRIVILEGE_SET;
-
-typedef struct lsa_r_enumprivsaccount
-{
-       uint32 ptr;
-       uint32 count;
-       PRIVILEGE_SET set;
-       NTSTATUS status;
-} LSA_R_ENUMPRIVSACCOUNT;
-
-typedef struct lsa_q_getsystemaccount
-{
-       POLICY_HND pol; /* policy handle */
-} LSA_Q_GETSYSTEMACCOUNT;
-
-typedef struct lsa_r_getsystemaccount
-{
-       uint32 access;
-       NTSTATUS status;
-} LSA_R_GETSYSTEMACCOUNT;
-
-
-typedef struct lsa_q_setsystemaccount
-{
-       POLICY_HND pol; /* policy handle */
-       uint32 access;
-} LSA_Q_SETSYSTEMACCOUNT;
-
-typedef struct lsa_r_setsystemaccount
-{
-       NTSTATUS status;
-} LSA_R_SETSYSTEMACCOUNT;
-
-
-typedef struct lsa_q_lookupprivvalue
-{
-       POLICY_HND pol; /* policy handle */
-       UNIHDR hdr_right;
-       UNISTR2 uni2_right;
-} LSA_Q_LOOKUPPRIVVALUE;
-
-typedef struct lsa_r_lookupprivvalue
-{
-       LUID luid;
-       NTSTATUS status;
-} LSA_R_LOOKUPPRIVVALUE;
-
-
-typedef struct lsa_q_addprivs
-{
-       POLICY_HND pol; /* policy handle */
-       uint32 count;
-       PRIVILEGE_SET set;
-} LSA_Q_ADDPRIVS;
-
-typedef struct lsa_r_addprivs
-{
-       NTSTATUS status;
-} LSA_R_ADDPRIVS;
-
-
-typedef struct lsa_q_removeprivs
-{
-       POLICY_HND pol; /* policy handle */
-       uint32 allrights;
-       uint32 ptr;
-       uint32 count;
-       PRIVILEGE_SET set;
-} LSA_Q_REMOVEPRIVS;
-
-typedef struct lsa_r_removeprivs
-{
-       NTSTATUS status;
-} LSA_R_REMOVEPRIVS;
-
-
 #endif /* _RPC_LSA_H */
 
 
index 06ad760c58fee7d11be50c688b622cafef670cb2..ac8a3c80c8ffbd1f42372db31c308d39ad4a9a6d 100644 (file)
 #define USER_RID_TYPE 0
 #define GROUP_RID_TYPE 1
 
-/* ENUM_HND */
-typedef struct enum_hnd_info
-{
-       uint32 ptr_hnd;          /* pointer to enumeration handle */
-       uint32 handle;           /* enumeration handle */
-
-} ENUM_HND;
-
-/* LOOKUP_LEVEL - switch value */
-typedef struct lookup_level_info
-{
-  uint16 value;
-
-} LOOKUP_LEVEL;
-
 /* DOM_SID2 - security id */
 typedef struct sid_info_2
 {
@@ -104,326 +89,6 @@ typedef struct sid_info_2
 
 } DOM_SID2;
 
-/* STRHDR - string header */
-typedef struct header_info
-{
-  uint16 str_str_len;
-  uint16 str_max_len;
-  uint32 buffer; /* non-zero */
-
-} STRHDR;
-
-/* UNIHDR - unicode string header */
-typedef struct unihdr_info
-{
-  uint16 uni_str_len;
-  uint16 uni_max_len;
-  uint32 buffer; /* usually has a value of 4 */
-
-} UNIHDR;
-
-/* UNIHDR2 - unicode string header and undocumented buffer */
-typedef struct unihdr2_info
-{
-  UNIHDR unihdr;
-  uint32 buffer; /* 32 bit buffer pointer */
-
-} UNIHDR2;
-
-/* clueless as to what maximum length should be */
-#define MAX_UNISTRLEN 256
-#define MAX_STRINGLEN 256
-#define MAX_BUFFERLEN 512
-
-/* UNISTR - unicode string size and buffer */
-typedef struct unistr_info
-{
-  /* unicode characters. ***MUST*** be little-endian. ***MUST*** be null-terminated */
-  uint16 *buffer;
-} UNISTR;
-
-/* BUFHDR - buffer header */
-typedef struct bufhdr_info
-{
-  uint32 buf_max_len;
-  uint32 buf_len;
-
-} BUFHDR;
-
-/* BUFFER2 - unicode string, size (in uint8 ascii chars) and buffer */
-/* pathetic.  some stupid team of \PIPE\winreg writers got the concept */
-/* of a unicode string different from the other \PIPE\ writers */
-typedef struct buffer2_info
-{
-  uint32 buf_max_len;
-  uint32 undoc;
-  uint32 buf_len;
-  /* unicode characters. ***MUST*** be little-endian. **NOT** necessarily null-terminated */
-  uint16 *buffer;
-
-} BUFFER2;
-
-/* BUFFER3 */
-typedef struct buffer3_info
-{
-  uint32 buf_max_len;
-  uint8  *buffer; /* Data */
-  uint32 buf_len;
-
-} BUFFER3;
-
-/* BUFFER5 */
-typedef struct buffer5_info
-{
-  uint32 buf_len;
-  uint16 *buffer; /* data */
-} BUFFER5;
-
-/* UNISTR2 - unicode string size (in uint16 unicode chars) and buffer */
-typedef struct unistr2_info
-{
-  uint32 uni_max_len;
-  uint32 undoc;
-  uint32 uni_str_len;
-  /* unicode characters. ***MUST*** be little-endian. 
-     **must** be null-terminated and the uni_str_len should include
-     the NULL character */
-  uint16 *buffer;
-
-} UNISTR2;
-
-/* STRING2 - string size (in uint8 chars) and buffer */
-typedef struct string2_info
-{
-  uint32 str_max_len;
-  uint32 undoc;
-  uint32 str_str_len;
-  uint8  *buffer; /* uint8 characters. **NOT** necessarily null-terminated */
-
-} STRING2;
-
-/* UNISTR3 - XXXX not sure about this structure */
-typedef struct unistr3_info
-{
-       uint32 uni_str_len;
-       UNISTR str;
-
-} UNISTR3;
-
-/* an element in a unicode string array */
-typedef struct
-{
-       uint16 length;
-       uint16 size;
-       uint32 ref_id;
-       UNISTR2 string;
-} UNISTR2_ARRAY_EL;
-
-/* an array of unicode strings */
-typedef struct 
-{
-       uint32 ref_id;
-       uint32 count;
-       UNISTR2_ARRAY_EL *strings;
-} UNISTR2_ARRAY;
-
-
-/* an element in a sid array */
-typedef struct
-{
-       uint32 ref_id;
-       DOM_SID2 sid;
-} SID_ARRAY_EL;
-
-/* an array of sids */
-typedef struct 
-{
-       uint32 ref_id;
-       uint32 count;
-       SID_ARRAY_EL *sids;
-} SID_ARRAY;
-
-/* DOM_RID2 - domain RID structure for ntlsa pipe */
-typedef struct domrid2_info
-{
-       uint8 type; /* value is SID_NAME_USE enum */
-       uint32 rid;
-       uint32 rid_idx; /* referenced domain index */
-
-} DOM_RID2;
-
-/* DOM_RID3 - domain RID structure for samr pipe */
-typedef struct domrid3_info
-{
-       uint32 rid;        /* domain-relative (to a SID) id */
-       uint32 type1;      /* value is 0x1 */
-       uint32 ptr_type;   /* undocumented pointer */
-       uint32 type2;      /* value is 0x1 */
-       uint32 unk; /* value is 0x2 */
-
-} DOM_RID3;
-
-/* DOM_RID4 - rid + user attributes */
-typedef struct domrid4_info
-{
-  uint32 unknown;
-  uint16 attr;
-  uint32 rid;  /* user RID */
-
-} DOM_RID4;
-
-/* DOM_CLNT_SRV - client / server names */
-typedef struct clnt_srv_info
-{
-  uint32  undoc_buffer; /* undocumented 32 bit buffer pointer */
-  UNISTR2 uni_logon_srv; /* logon server name */
-  uint32  undoc_buffer2; /* undocumented 32 bit buffer pointer */
-  UNISTR2 uni_comp_name; /* client machine name */
-
-} DOM_CLNT_SRV;
-
-/* DOM_LOG_INFO - login info */
-typedef struct log_info
-{
-  uint32  undoc_buffer; /* undocumented 32 bit buffer pointer */
-  UNISTR2 uni_logon_srv; /* logon server name */
-  UNISTR2 uni_acct_name; /* account name */
-  uint16  sec_chan;      /* secure channel type */
-  UNISTR2 uni_comp_name; /* client machine name */
-
-} DOM_LOG_INFO;
-
-/* DOM_CHAL - challenge info */
-typedef struct chal_info
-{
-    uchar data[8]; /* credentials */
-} DOM_CHAL;
-/* DOM_CREDs - timestamped client or server credentials */
-typedef struct cred_info
-{
-    DOM_CHAL challenge; /* credentials */
-    UTIME timestamp;    /* credential time-stamp */
-} DOM_CRED;
-
-/* DOM_CLNT_INFO - client info */
-typedef struct clnt_info
-{
-  DOM_LOG_INFO login;
-  DOM_CRED     cred;
-
-} DOM_CLNT_INFO;
-
-/* DOM_CLNT_INFO2 - client info */
-typedef struct clnt_info2
-{
-  DOM_CLNT_SRV login;
-  uint32        ptr_cred;
-  DOM_CRED      cred;
-
-} DOM_CLNT_INFO2;
-
-/* DOM_LOGON_ID - logon id */
-typedef struct logon_info
-{
-  uint32 low;
-  uint32 high;
-
-} DOM_LOGON_ID;
-
-/* OWF INFO */
-typedef struct owf_info
-{
-  uint8 data[16];
-
-} OWF_INFO;
-
-
-/* DOM_GID - group id + user attributes */
-typedef struct gid_info
-{
-  uint32 g_rid;  /* a group RID */
-  uint32 attr;
-
-} DOM_GID;
-
-/* POLICY_HND */
-typedef struct lsa_policy_info
-{
-       uint32 data1;
-       uint32 data2;
-       uint16 data3;
-       uint16 data4;
-       uint8 data5[8];
-
-#ifdef __INSURE__
-
-       /* To prevent the leakage of policy handles mallocate a bit of
-          memory when a policy handle is created and free it when the
-          handle is closed.  This should cause Insure to flag an error
-          when policy handles are overwritten or fall out of scope without
-          being freed. */
-
-       char *marker;
-#endif
-
-} POLICY_HND;
-
-/*
- * A client connection's state, pipe name, 
- * user credentials, etc...
- */
-typedef struct _cli_auth_fns cli_auth_fns;
-struct user_creds;
-struct cli_connection {
-
-        char                    *srv_name;
-        char                    *pipe_name;
-        struct user_creds       usr_creds;
-
-        struct cli_state        *pCli_state;
-
-        cli_auth_fns            *auth;
-
-        void                    *auth_info;
-        void                    *auth_creds;
-};
-
-
-/* 
- * Associate a POLICY_HND with a cli_connection
- */
-typedef struct rpc_hnd_node {
-
-       POLICY_HND              hnd;
-       struct cli_connection   *cli;
-
-} RPC_HND_NODE;
-
-typedef struct uint64_s
-{
-       uint32 low;
-       uint32 high;
-} UINT64_S;
-
-/* BUFHDR2 - another buffer header, with info level */
-typedef struct bufhdr2_info
-{
-       uint32 info_level;
-       uint32 length;          /* uint8 chars */
-       uint32 buffer;
-
-}
-BUFHDR2;
-
-/* BUFFER4 - simple length and buffer */
-typedef struct buffer4_info
-{
-       uint32 buf_len;
-       uint8 buffer[MAX_BUFFERLEN];
-
-}
-BUFFER4;
 
 
 #endif /* _RPC_MISC_H */
index fb849f82380600154408d72c247e5c581ad61e60..68a3e42cf1118a19669393ca1825c2786eab5ec3 100644 (file)
 #define SAM_DATABASE_BUILTIN   0x01 /* BUILTIN users and groups */
 #define SAM_DATABASE_PRIVS     0x02 /* Privileges */
 
-#if 0
-/* I think this is correct - it's what gets parsed on the wire. JRA. */
-/* NET_USER_INFO_2 */
-typedef struct net_user_info_2
-{
-       uint32 ptr_user_info;
 
-       NTTIME logon_time;            /* logon time */
-       NTTIME logoff_time;           /* logoff time */
-       NTTIME kickoff_time;          /* kickoff time */
-       NTTIME pass_last_set_time;    /* password last set time */
-       NTTIME pass_can_change_time;  /* password can change time */
-       NTTIME pass_must_change_time; /* password must change time */
-
-       UNIHDR hdr_user_name;    /* username unicode string header */
-       UNIHDR hdr_full_name;    /* user's full name unicode string header */
-       UNIHDR hdr_logon_script; /* logon script unicode string header */
-       UNIHDR hdr_profile_path; /* profile path unicode string header */
-       UNIHDR hdr_home_dir;     /* home directory unicode string header */
-       UNIHDR hdr_dir_drive;    /* home directory drive unicode string header */
-
-       uint16 logon_count;  /* logon count */
-       uint16 bad_pw_count; /* bad password count */
-
-       uint32 user_id;       /* User ID */
-       uint32 group_id;      /* Group ID */
-       uint32 num_groups;    /* num groups */
-       uint32 buffer_groups; /* undocumented buffer pointer to groups. */
-       uint32 user_flgs;     /* user flags */
-
-       uint8 user_sess_key[16]; /* unused user session key */
-
-       UNIHDR hdr_logon_srv; /* logon server unicode string header */
-       UNIHDR hdr_logon_dom; /* logon domain unicode string header */
-
-       uint32 buffer_dom_id; /* undocumented logon domain id pointer */
-       uint8 padding[40];    /* unused padding bytes.  expansion room */
-
-       UNISTR2 uni_user_name;    /* username unicode string */
-       UNISTR2 uni_full_name;    /* user's full name unicode string */
-       UNISTR2 uni_logon_script; /* logon script unicode string */
-       UNISTR2 uni_profile_path; /* profile path unicode string */
-       UNISTR2 uni_home_dir;     /* home directory unicode string */
-       UNISTR2 uni_dir_drive;    /* home directory drive unicode string */
-
-       uint32 num_groups2;        /* num groups */
-       DOM_GID *gids; /* group info */
-
-       UNISTR2 uni_logon_srv; /* logon server unicode string */
-       UNISTR2 uni_logon_dom; /* logon domain unicode string */
-
-       DOM_SID2 dom_sid;           /* domain SID */
-
-       uint32 num_other_groups;        /* other groups */
-       DOM_GID *other_gids; /* group info */
-       DOM_SID2 *other_sids; /* undocumented - domain SIDs */
-
-} NET_USER_INFO_2;
-#endif
-
-/* NET_USER_INFO_3 */
-typedef struct net_user_info_3
-{
-       uint32 ptr_user_info;
-
-       NTTIME logon_time;            /* logon time */
-       NTTIME logoff_time;           /* logoff time */
-       NTTIME kickoff_time;          /* kickoff time */
-       NTTIME pass_last_set_time;    /* password last set time */
-       NTTIME pass_can_change_time;  /* password can change time */
-       NTTIME pass_must_change_time; /* password must change time */
-
-       UNIHDR hdr_user_name;    /* username unicode string header */
-       UNIHDR hdr_full_name;    /* user's full name unicode string header */
-       UNIHDR hdr_logon_script; /* logon script unicode string header */
-       UNIHDR hdr_profile_path; /* profile path unicode string header */
-       UNIHDR hdr_home_dir;     /* home directory unicode string header */
-       UNIHDR hdr_dir_drive;    /* home directory drive unicode string header */
-
-       uint16 logon_count;  /* logon count */
-       uint16 bad_pw_count; /* bad password count */
-
-       uint32 user_rid;       /* User RID */
-       uint32 group_rid;      /* Group RID */
-
-       uint32 num_groups;    /* num groups */
-       uint32 buffer_groups; /* undocumented buffer pointer to groups. */
-       uint32 user_flgs;     /* user flags */
-
-       uint8 user_sess_key[16]; /* unused user session key */
-
-       UNIHDR hdr_logon_srv; /* logon server unicode string header */
-       UNIHDR hdr_logon_dom; /* logon domain unicode string header */
-
-       uint32 buffer_dom_id; /* undocumented logon domain id pointer */
-       uint8 padding[40];    /* unused padding bytes.  expansion room */
-
-       uint32 num_other_sids; /* number of foreign/trusted domain sids */
-       uint32 buffer_other_sids;
-       
-       UNISTR2 uni_user_name;    /* username unicode string */
-       UNISTR2 uni_full_name;    /* user's full name unicode string */
-       UNISTR2 uni_logon_script; /* logon script unicode string */
-       UNISTR2 uni_profile_path; /* profile path unicode string */
-       UNISTR2 uni_home_dir;     /* home directory unicode string */
-       UNISTR2 uni_dir_drive;    /* home directory drive unicode string */
-
-       uint32 num_groups2;        /* num groups */
-       DOM_GID *gids; /* group info */
-
-       UNISTR2 uni_logon_srv; /* logon server unicode string */
-       UNISTR2 uni_logon_dom; /* logon domain unicode string */
-
-       DOM_SID2 dom_sid;           /* domain SID */
-
-       uint32 num_other_groups;        /* other groups */
-       DOM_GID *other_gids; /* group info */
-       DOM_SID2 *other_sids; /* foreign/trusted domain SIDs */
-
-} NET_USER_INFO_3;
-
-
-/* NETLOGON_INFO_1 - pdc status info, i presume */
-typedef struct netlogon_1_info
-{
-       uint32 flags;            /* 0x0 - undocumented */
-       uint32 pdc_status;       /* 0x0 - undocumented */
-
-} NETLOGON_INFO_1;
-
-/* NETLOGON_INFO_2 - pdc status info, plus trusted domain info */
-typedef struct netlogon_2_info
-{
-       uint32  flags;            /* 0x0 - undocumented */
-       uint32  pdc_status;       /* 0x0 - undocumented */
-       uint32  ptr_trusted_dc_name; /* pointer to trusted domain controller name */
-       uint32  tc_status;           /* 0x051f - ERROR_NO_LOGON_SERVERS */
-       UNISTR2 uni_trusted_dc_name; /* unicode string - trusted dc name */
-
-} NETLOGON_INFO_2;
-
-/* NETLOGON_INFO_3 - logon status info, i presume */
-typedef struct netlogon_3_info
-{
-       uint32 flags;            /* 0x0 - undocumented */
-       uint32 logon_attempts;   /* number of logon attempts */
-       uint32 reserved_1;       /* 0x0 - undocumented */
-       uint32 reserved_2;       /* 0x0 - undocumented */
-       uint32 reserved_3;       /* 0x0 - undocumented */
-       uint32 reserved_4;       /* 0x0 - undocumented */
-       uint32 reserved_5;       /* 0x0 - undocumented */
-
-} NETLOGON_INFO_3;
-
-/********************************************************
- Logon Control Query
-
- This is generated by a nltest /bdc_query:DOMAIN
-
- query_level 0x1, function_code 0x1
-
- ********************************************************/
-
-/* NET_Q_LOGON_CTRL - LSA Netr Logon Control */
-
-typedef struct net_q_logon_ctrl_info
-{
-       uint32 ptr;
-       UNISTR2 uni_server_name;
-       uint32 function_code;
-       uint32 query_level;
-} NET_Q_LOGON_CTRL;
-
-/* NET_R_LOGON_CTRL - LSA Netr Logon Control */
-
-typedef struct net_r_logon_ctrl_info
-{
-       uint32 switch_value;
-       uint32 ptr;
-
-       union {
-               NETLOGON_INFO_1 info1;
-       } logon;
-
-       NTSTATUS status;
-} NET_R_LOGON_CTRL;
-
-/********************************************************
- Logon Control2 Query
-
- query_level 0x1 - pdc status
- query_level 0x3 - number of logon attempts.
-
- ********************************************************/
-
-/* NET_Q_LOGON_CTRL2 - LSA Netr Logon Control 2 */
-typedef struct net_q_logon_ctrl2_info
-{
-       uint32       ptr;             /* undocumented buffer pointer */
-       UNISTR2      uni_server_name; /* server name, starting with two '\'s */
-       
-       uint32       function_code; /* 0x1 */
-       uint32       query_level;   /* 0x1, 0x3 */
-       uint32       switch_value;  /* 0x1 */
-
-} NET_Q_LOGON_CTRL2;
-
-/*******************************************************
- Logon Control Response
-
- switch_value is same as query_level in request 
- *******************************************************/
-
-/* NET_R_LOGON_CTRL2 - response to LSA Logon Control2 */
-typedef struct net_r_logon_ctrl2_info
-{
-       uint32       switch_value;  /* 0x1, 0x3 */
-       uint32       ptr;
-
-       union
-       {
-               NETLOGON_INFO_1 info1;
-               NETLOGON_INFO_2 info2;
-               NETLOGON_INFO_3 info3;
-
-       } logon;
-
-       NTSTATUS status; /* return code */
-
-} NET_R_LOGON_CTRL2;
-
-/* NET_Q_TRUST_DOM_LIST - LSA Query Trusted Domains */
-typedef struct net_q_trust_dom_info
-{
-       uint32       ptr;             /* undocumented buffer pointer */
-       UNISTR2      uni_server_name; /* server name, starting with two '\'s */
-
-} NET_Q_TRUST_DOM_LIST;
-
-#define MAX_TRUST_DOMS 1
-
-/* NET_R_TRUST_DOM_LIST - response to LSA Trusted Domains */
-typedef struct net_r_trust_dom_info
-{
-       UNISTR2 uni_trust_dom_name[MAX_TRUST_DOMS];
-
-       NTSTATUS status; /* return code */
-
-} NET_R_TRUST_DOM_LIST;
-
-
-/* NEG_FLAGS */
-typedef struct neg_flags_info
-{
-    uint32 neg_flags; /* negotiated flags */
-
-} NEG_FLAGS;
-
-
-/* NET_Q_REQ_CHAL */
-typedef struct net_q_req_chal_info
-{
-    uint32  undoc_buffer; /* undocumented buffer pointer */
-    UNISTR2 uni_logon_srv; /* logon server unicode string */
-    UNISTR2 uni_logon_clnt; /* logon client unicode string */
-    DOM_CHAL clnt_chal; /* client challenge */
-
-} NET_Q_REQ_CHAL;
-
-
-/* NET_R_REQ_CHAL */
-typedef struct net_r_req_chal_info
-{
-       DOM_CHAL srv_chal; /* server challenge */
-       NTSTATUS status; /* return code */
-} NET_R_REQ_CHAL;
-
-/* NET_Q_AUTH */
-typedef struct net_q_auth_info
-{
-       DOM_LOG_INFO clnt_id; /* client identification info */
-       DOM_CHAL clnt_chal;     /* client-calculated credentials */
-} NET_Q_AUTH;
-
-/* NET_R_AUTH */
-typedef struct net_r_auth_info
-{
-       DOM_CHAL srv_chal;     /* server-calculated credentials */
-       NTSTATUS status; /* return code */
-} NET_R_AUTH;
-
-/* NET_Q_AUTH_2 */
-typedef struct net_q_auth2_info
-{
-    DOM_LOG_INFO clnt_id; /* client identification info */
-    DOM_CHAL clnt_chal;     /* client-calculated credentials */
-
-    NEG_FLAGS clnt_flgs; /* usually 0x0000 01ff */
-
-} NET_Q_AUTH_2;
-
-
-/* NET_R_AUTH_2 */
-typedef struct net_r_auth2_info
-{
-       DOM_CHAL srv_chal;     /* server-calculated credentials */
-       NEG_FLAGS srv_flgs; /* usually 0x0000 01ff */
-       NTSTATUS status; /* return code */
-} NET_R_AUTH_2;
-
-/* NET_Q_AUTH_3 */
-typedef struct net_q_auth3_info
-{
-    DOM_LOG_INFO clnt_id;      /* client identification info */
-    DOM_CHAL clnt_chal;                /* client-calculated credentials */
-    NEG_FLAGS clnt_flgs;       /* usually 0x6007 ffff */
-} NET_Q_AUTH_3;
-
-/* NET_R_AUTH_3 */
-typedef struct net_r_auth3_info
-{
-       DOM_CHAL srv_chal;      /* server-calculated credentials */
-       NEG_FLAGS srv_flgs;     /* usually 0x6007 ffff */
-       uint32 unknown;         /* 0x0000045b */
-       NTSTATUS status;        /* return code */
-} NET_R_AUTH_3;
-
-
-/* NET_Q_SRV_PWSET */
-typedef struct net_q_srv_pwset_info
-{
-    DOM_CLNT_INFO clnt_id; /* client identification/authentication info */
-    uint8 pwd[16]; /* new password - undocumented. */
-
-} NET_Q_SRV_PWSET;
-    
-/* NET_R_SRV_PWSET */
-typedef struct net_r_srv_pwset_info
-{
-    DOM_CRED srv_cred;     /* server-calculated credentials */
-
-  NTSTATUS status; /* return code */
-
-} NET_R_SRV_PWSET;
-
-/* NET_ID_INFO_2 */
-typedef struct net_network_info_2
-{
-       uint32            ptr_id_info2;        /* pointer to id_info_2 */
-       UNIHDR            hdr_domain_name;     /* domain name unicode header */
-       uint32            param_ctrl;          /* param control (0x2) */
-       DOM_LOGON_ID      logon_id;            /* logon ID */
-       UNIHDR            hdr_user_name;       /* user name unicode header */
-       UNIHDR            hdr_wksta_name;      /* workstation name unicode header */
-       uint8             lm_chal[8];          /* lan manager 8 byte challenge */
-       STRHDR            hdr_nt_chal_resp;    /* nt challenge response */
-       STRHDR            hdr_lm_chal_resp;    /* lm challenge response */
-
-       UNISTR2           uni_domain_name;     /* domain name unicode string */
-       UNISTR2           uni_user_name;       /* user name unicode string */
-       UNISTR2           uni_wksta_name;      /* workgroup name unicode string */
-       STRING2           nt_chal_resp;        /* nt challenge response */
-       STRING2           lm_chal_resp;        /* lm challenge response */
-
-} NET_ID_INFO_2;
-
-/* NET_ID_INFO_1 */
-typedef struct id_info_1
-{
-       uint32            ptr_id_info1;        /* pointer to id_info_1 */
-       UNIHDR            hdr_domain_name;     /* domain name unicode header */
-       uint32            param_ctrl;          /* param control */
-       DOM_LOGON_ID      logon_id;            /* logon ID */
-       UNIHDR            hdr_user_name;       /* user name unicode header */
-       UNIHDR            hdr_wksta_name;      /* workstation name unicode header */
-       OWF_INFO          lm_owf;              /* LM OWF Password */
-       OWF_INFO          nt_owf;              /* NT OWF Password */
-       UNISTR2           uni_domain_name;     /* domain name unicode string */
-       UNISTR2           uni_user_name;       /* user name unicode string */
-       UNISTR2           uni_wksta_name;      /* workgroup name unicode string */
-
-} NET_ID_INFO_1;
-
-#define INTERACTIVE_LOGON_TYPE 1
-#define NET_LOGON_TYPE 2
-
-/* NET_ID_INFO_CTR */
-typedef struct net_id_info_ctr_info
-{
-  uint16         switch_value;
-  
-  union
-  {
-    NET_ID_INFO_1 id1; /* auth-level 1 - interactive user login */
-    NET_ID_INFO_2 id2; /* auth-level 2 - workstation referred login */
-
-  } auth;
-  
-} NET_ID_INFO_CTR;
-
-/* SAM_INFO - sam logon/off id structure */
-typedef struct sam_info
-{
-  DOM_CLNT_INFO2  client;
-  uint32          ptr_rtn_cred; /* pointer to return credentials */
-  DOM_CRED        rtn_cred; /* return credentials */
-  uint16          logon_level;
-  NET_ID_INFO_CTR *ctr;
-
-} DOM_SAM_INFO;
-
-/* NET_Q_SAM_LOGON */
-typedef struct net_q_sam_logon_info
-{
-    DOM_SAM_INFO sam_id;
-       uint16          validation_level;
-
-} NET_Q_SAM_LOGON;
-
-/* NET_R_SAM_LOGON */
-typedef struct net_r_sam_logon_info
-{
-    uint32 buffer_creds; /* undocumented buffer pointer */
-    DOM_CRED srv_creds; /* server credentials.  server time stamp appears to be ignored. */
-    
-       uint16 switch_value; /* 3 - indicates type of USER INFO */
-    NET_USER_INFO_3 *user;
-
-    uint32 auth_resp; /* 1 - Authoritative response; 0 - Non-Auth? */
-
-  NTSTATUS status; /* return code */
-
-} NET_R_SAM_LOGON;
-
-
-/* NET_Q_SAM_LOGOFF */
-typedef struct net_q_sam_logoff_info
-{
-    DOM_SAM_INFO sam_id;
-
-} NET_Q_SAM_LOGOFF;
-
-/* NET_R_SAM_LOGOFF */
-typedef struct net_r_sam_logoff_info
-{
-    uint32 buffer_creds; /* undocumented buffer pointer */
-    DOM_CRED srv_creds; /* server credentials.  server time stamp appears to be ignored. */
-    
-  NTSTATUS status; /* return code */
-
-} NET_R_SAM_LOGOFF;
-
-/* NET_Q_SAM_SYNC */
-typedef struct net_q_sam_sync_info
-{
-       UNISTR2 uni_srv_name; /* \\PDC */
-       UNISTR2 uni_cli_name; /* BDC */
-       DOM_CRED cli_creds;
-       DOM_CRED ret_creds;
-
-       uint32 database_id;
-       uint32 restart_state;
-       uint32 sync_context;
-
-       uint32 max_size;       /* preferred maximum length */
-
-} NET_Q_SAM_SYNC;
-
-/* SAM_DELTA_HDR */
-typedef struct sam_delta_hdr_info
-{
-       uint16 type;  /* type of structure attached */
-       uint16 type2;
-       uint32 target_rid;
-
-       uint32 type3;
-       uint32 ptr_delta;
-
-} SAM_DELTA_HDR;
-
-/* SAM_DOMAIN_INFO (0x1) */
-typedef struct sam_domain_info_info
-{
-       UNIHDR hdr_dom_name;
-       UNIHDR hdr_oem_info;
-
-       UINT64_S force_logoff;
-       uint16   min_pwd_len;
-       uint16   pwd_history_len;
-       UINT64_S max_pwd_age;
-       UINT64_S min_pwd_age;
-       UINT64_S dom_mod_count;
-       NTTIME   creation_time;
-
-       BUFHDR2 hdr_sec_desc; /* security descriptor */
-       UNIHDR hdr_unknown;
-       uint8 reserved[40];
-
-       UNISTR2 uni_dom_name;
-       UNISTR2 buf_oem_info; /* never seen */
-
-       BUFFER4 buf_sec_desc;
-       UNISTR2 buf_unknown;
-
-} SAM_DOMAIN_INFO;
-
-/* SAM_GROUP_INFO (0x2) */
-typedef struct sam_group_info_info
-{
-       UNIHDR hdr_grp_name;
-       DOM_GID gid;
-       UNIHDR hdr_grp_desc;
-       BUFHDR2 hdr_sec_desc;  /* security descriptor */
-       uint8 reserved[48];
-
-       UNISTR2 uni_grp_name;
-       UNISTR2 uni_grp_desc;
-       BUFFER4 buf_sec_desc;
-
-} SAM_GROUP_INFO;
-
-/* SAM_PWD */
-typedef struct sam_passwd_info
-{
-       /* this structure probably contains password history */
-       /* this is probably a count of lm/nt pairs */
-       uint32 unk_0; /* 0x0000 0002 */
-
-       UNIHDR hdr_lm_pwd;
-       uint8  buf_lm_pwd[16];
-
-       UNIHDR hdr_nt_pwd;
-       uint8  buf_nt_pwd[16];
-
-       UNIHDR hdr_empty_lm;
-       UNIHDR hdr_empty_nt;
-
-} SAM_PWD;
-
-/* SAM_ACCOUNT_INFO (0x5) */
-typedef struct sam_account_info_info
-{
-       UNIHDR hdr_acct_name;
-       UNIHDR hdr_full_name;
-
-       uint32 user_rid;
-       uint32 group_rid;
-
-       UNIHDR hdr_home_dir;
-       UNIHDR hdr_dir_drive;
-       UNIHDR hdr_logon_script;
-       UNIHDR hdr_acct_desc;
-       UNIHDR hdr_workstations;
-
-       NTTIME logon_time;
-       NTTIME logoff_time;
-
-       uint32 logon_divs; /* 0xA8 */
-       uint32 ptr_logon_hrs;
-
-       uint16 bad_pwd_count;
-       uint16 logon_count;
-       NTTIME pwd_last_set_time;
-       NTTIME acct_expiry_time;
-
-       uint32 acb_info;
-       uint8 nt_pwd[16];
-       uint8 lm_pwd[16];
-       uint8 nt_pwd_present;
-       uint8 lm_pwd_present;
-       uint8 pwd_expired;
-
-       UNIHDR hdr_comment;
-       UNIHDR hdr_parameters;
-       uint16 country;
-       uint16 codepage;
-
-       BUFHDR2 hdr_sec_desc;  /* security descriptor */
-
-       UNIHDR  hdr_profile;
-       UNIHDR  hdr_reserved[3];  /* space for more strings */
-       uint32  dw_reserved[4];   /* space for more data - first two seem to
-                                    be an NTTIME */
-
-       UNISTR2 uni_acct_name;
-       UNISTR2 uni_full_name;
-       UNISTR2 uni_home_dir;
-       UNISTR2 uni_dir_drive;
-       UNISTR2 uni_logon_script;
-       UNISTR2 uni_acct_desc;
-       UNISTR2 uni_workstations;
-
-       uint32 unknown1; /* 0x4EC */
-       uint32 unknown2; /* 0 */
-
-       BUFFER4 buf_logon_hrs;
-       UNISTR2 uni_comment;
-       UNISTR2 uni_parameters;
-       SAM_PWD pass;
-       BUFFER4 buf_sec_desc;
-       UNISTR2 uni_profile;
-
-} SAM_ACCOUNT_INFO;
-
-/* SAM_GROUP_MEM_INFO (0x8) */
-typedef struct sam_group_mem_info_info
-{
-       uint32 ptr_rids;
-       uint32 ptr_attribs;
-       uint32 num_members;
-       uint8 unknown[16];
-
-       uint32 num_members2;
-       uint32 *rids;
-
-       uint32 num_members3;
-       uint32 *attribs;
-
-} SAM_GROUP_MEM_INFO;
-
-/* SAM_ALIAS_INFO (0x9) */
-typedef struct sam_alias_info_info
-{
-       UNIHDR hdr_als_name;
-       uint32 als_rid;
-       BUFHDR2 hdr_sec_desc;  /* security descriptor */
-       UNIHDR hdr_als_desc;
-       uint8 reserved[40];
-
-       UNISTR2 uni_als_name;
-       BUFFER4 buf_sec_desc;
-       UNISTR2 uni_als_desc;
-
-} SAM_ALIAS_INFO;
-
-/* SAM_ALIAS_MEM_INFO (0xC) */
-typedef struct sam_alias_mem_info_info
-{
-       uint32 num_members;
-       uint32 ptr_members;
-       uint8 unknown[16];
-
-       uint32 num_sids;
-       uint32 *ptr_sids;
-       DOM_SID2 *sids;
-
-} SAM_ALIAS_MEM_INFO;
-
-
-/* SAM_DELTA_POLICY (0x0D) */
-typedef struct
-{
-       uint32   max_log_size; /* 0x5000 */
-       UINT64_S audit_retention_period; /* 0 */
-       uint32   auditing_mode; /* 0 */
-       uint32   num_events;
-       uint32   ptr_events;
-       UNIHDR   hdr_dom_name;
-       uint32   sid_ptr;
-
-       uint32   paged_pool_limit; /* 0x02000000 */
-       uint32   non_paged_pool_limit; /* 0x00100000 */
-       uint32   min_workset_size; /* 0x00010000 */
-       uint32   max_workset_size; /* 0x0f000000 */
-       uint32   page_file_limit; /* 0 */
-       UINT64_S time_limit; /* 0 */
-       NTTIME   modify_time; /* 0x3c*/
-       NTTIME   create_time; /* a7080110 */
-       BUFHDR2  hdr_sec_desc;
-
-       uint32   num_event_audit_options;
-       uint32   event_audit_option;
-
-       UNISTR2  domain_name;
-       DOM_SID2 domain_sid;
-
-       BUFFER4  buf_sec_desc;
-} SAM_DELTA_POLICY;
-
-/* SAM_DELTA_TRUST_DOMS */
-typedef struct
-{
-       uint32 buf_size;
-       SEC_DESC *sec_desc;
-       DOM_SID2 sid;
-       UNIHDR hdr_domain;
-       
-       uint32 unknown0;
-       uint32 unknown1;
-       uint32 unknown2;
-       
-       uint32 buf_size2;
-       uint32 ptr;
-
-       uint32 unknown3;
-       UNISTR2 domain;
-
-} SAM_DELTA_TRUSTDOMS;
-
-/* SAM_DELTA_PRIVS (0x10) */
-typedef struct
-{
-       DOM_SID2 sid;
-
-       uint32 priv_count;
-       uint32 priv_control;
-
-       uint32 priv_attr_ptr;
-       uint32 priv_name_ptr;
-
-       uint32   paged_pool_limit; /* 0x02000000 */
-       uint32   non_paged_pool_limit; /* 0x00100000 */
-       uint32   min_workset_size; /* 0x00010000 */
-       uint32   max_workset_size; /* 0x0f000000 */
-       uint32   page_file_limit; /* 0 */
-       UINT64_S time_limit; /* 0 */
-       uint32   system_flags; /* 1 */
-       BUFHDR2  hdr_sec_desc;
-       
-       uint32 buf_size2;
-       
-       uint32 attribute_count;
-       uint32 *attributes;
-       
-       uint32 privlist_count;
-       UNIHDR *hdr_privslist;
-       UNISTR2 *uni_privslist;
-
-       BUFFER4 buf_sec_desc;
-} SAM_DELTA_PRIVS;
-
-/* SAM_DELTA_SECRET */
-typedef struct
-{
-       uint32 buf_size;
-       SEC_DESC *sec_desc;
-       UNISTR2 secret;
-
-       uint32 count1;
-       uint32 count2;
-       uint32 ptr;
-       NTTIME time1;
-       uint32 count3;
-       uint32 count4;
-       uint32 ptr2;
-       NTTIME time2;
-       uint32 unknow1;
-
-       uint32 buf_size2;
-       uint32 ptr3;
-       uint32 unknow2; /* 0x0 12 times */
-
-       uint32 chal_len;
-       uint32 reserved1; /* 0 */
-       uint32 chal_len2;
-       uint8 chal[16];
-
-       uint32 key_len;
-       uint32 reserved2; /* 0 */
-       uint32 key_len2;
-       uint8 key[8];
-
-       uint32 buf_size3;
-       SEC_DESC *sec_desc2;
-
-} SAM_DELTA_SECRET;
-
-/* SAM_DELTA_MOD_COUNT (0x16) */
-typedef struct
-{
-        uint32 seqnum;
-        uint32 dom_mod_count_ptr;
-       UINT64_S dom_mod_count;  /* domain mod count at last sync */
-} SAM_DELTA_MOD_COUNT;
-
-typedef union sam_delta_ctr_info
-{
-       SAM_DOMAIN_INFO    domain_info ;
-       SAM_GROUP_INFO     group_info  ;
-       SAM_ACCOUNT_INFO   account_info;
-       SAM_GROUP_MEM_INFO grp_mem_info;
-       SAM_ALIAS_INFO     alias_info  ;
-       SAM_ALIAS_MEM_INFO als_mem_info;
-       SAM_DELTA_POLICY   policy_info;
-       SAM_DELTA_PRIVS    privs_info;
-       SAM_DELTA_MOD_COUNT mod_count;
-       SAM_DELTA_TRUSTDOMS trustdoms_info;
-       SAM_DELTA_SECRET   secret_info;
-} SAM_DELTA_CTR;
-
-/* NET_R_SAM_SYNC */
-typedef struct net_r_sam_sync_info
-{
-       DOM_CRED srv_creds;
-
-       uint32 sync_context;
-
-       uint32 ptr_deltas;
-       uint32 num_deltas;
-       uint32 ptr_deltas2;
-       uint32 num_deltas2;
-
-       SAM_DELTA_HDR *hdr_deltas;
-       SAM_DELTA_CTR *deltas;
-
-       NTSTATUS status;
-} NET_R_SAM_SYNC;
-
-/* NET_Q_SAM_DELTAS */
-typedef struct net_q_sam_deltas_info
-{
-       UNISTR2 uni_srv_name;
-       UNISTR2 uni_cli_name;
-       DOM_CRED cli_creds;
-       DOM_CRED ret_creds;
-
-       uint32 database_id;
-       UINT64_S dom_mod_count;  /* domain mod count at last sync */
-
-       uint32 max_size;       /* preferred maximum length */
-
-} NET_Q_SAM_DELTAS;
-
-/* NET_R_SAM_DELTAS */
-typedef struct net_r_sam_deltas_info
-{
-       DOM_CRED srv_creds;
-
-       UINT64_S dom_mod_count;   /* new domain mod count */
-
-       uint32 ptr_deltas;
-       uint32 num_deltas;
-       uint32 num_deltas2;
-
-       SAM_DELTA_HDR *hdr_deltas;
-       SAM_DELTA_CTR *deltas;
-
-       NTSTATUS status;
-} NET_R_SAM_DELTAS;
 
 #endif /* _RPC_NETLOGON_H */
index 3e3430d1471ae5a164b4932ebaf634b8f111914b..5e48d716b98a0dbef64096715de3c95cf66b7ed3 100644 (file)
@@ -158,46 +158,6 @@ void init_valid_table(void)
 }
 
 
-/*******************************************************************
- Convert a (little-endian) UNISTR2 structure to an ASCII string
-********************************************************************/
-static void unistr2_to_ascii(char *dest, const UNISTR2 *str, size_t maxlen)
-{
-       if (str == NULL) {
-               *dest='\0';
-               return;
-       }
-       pull_ucs2(NULL, dest, str->buffer, maxlen, str->uni_str_len*2, STR_NOALIGN);
-}
-
-/*******************************************************************
-give a static string for displaying a UNISTR2
-********************************************************************/
-const char *unistr2_static(TALLOC_CTX *mem_ctx, const UNISTR2 *str)
-{
-       pstring ret;
-       unistr2_to_ascii(ret, str, sizeof(ret));
-       return talloc_strdup(mem_ctx, ret);
-}
-
-
-/*******************************************************************
- duplicate a UNISTR2 string into a null terminated char*
- using a talloc context
-********************************************************************/
-char *unistr2_tdup(TALLOC_CTX *ctx, const UNISTR2 *str)
-{
-       char *s;
-       int maxlen = (str->uni_str_len+1)*4;
-       if (!str->buffer) return NULL;
-       s = (char *)talloc(ctx, maxlen); /* convervative */
-       if (!s) return NULL;
-       pull_ucs2(NULL, s, str->buffer, maxlen, str->uni_str_len*2, 
-                 STR_NOALIGN);
-       return s;
-}
-
-
 /*******************************************************************
  Convert a wchar to upper case.
 ********************************************************************/
index 681d4071dbb4ee3dc445213e1b20d8cf0b6c13cb..c57646ca3114de110ece1d40bf550f735fe4ec0d 100644 (file)
@@ -68,6 +68,9 @@ enum NTLM_MESSAGE_TYPE
 #define NTLMSSP_NAME_TYPE_SERVER_DNS  0x03
 #define NTLMSSP_NAME_TYPE_DOMAIN_DNS  0x04
 
+
+#define NTLMSSP_SIGN_VERSION 0xa
+
 typedef struct ntlmssp_state 
 {
        TALLOC_CTX *mem_ctx;
index 0d521bae8ac42c7421f6db043bee74a48c0e3217..2c8f7e742349abd78e3f7e4773bf2ed2801fead7 100644 (file)
 */
 
 #include "includes.h"
-
-/****************************************************************************
-represent a credential as a string
-****************************************************************************/
-char *credstr(const uchar *cred)
-{
-       static fstring buf;
-       slprintf(buf, sizeof(buf) - 1, "%02X%02X%02X%02X%02X%02X%02X%02X",
-               cred[0], cred[1], cred[2], cred[3], 
-               cred[4], cred[5], cred[6], cred[7]);
-       return buf;
-}
-
-
-/****************************************************************************
-  setup the session key. 
-Input: 8 byte challenge block
-       8 byte server challenge block
-      16 byte md4 encrypted password
-Output:
-      8 byte session key
-****************************************************************************/
-void cred_session_key(const DOM_CHAL *clnt_chal, const DOM_CHAL *srv_chal, const uchar *pass, 
-                     uchar session_key[8])
-{
-       uint32 sum[2];
-       unsigned char sum2[8];
-
-       sum[0] = IVAL(clnt_chal->data, 0) + IVAL(srv_chal->data, 0);
-       sum[1] = IVAL(clnt_chal->data, 4) + IVAL(srv_chal->data, 4);
-
-       SIVAL(sum2,0,sum[0]);
-       SIVAL(sum2,4,sum[1]);
-
-       cred_hash1(session_key, sum2, pass);
-
-       /* debug output */
-       DEBUG(4,("cred_session_key\n"));
-
-       DEBUG(5,("      clnt_chal: %s\n", credstr(clnt_chal->data)));
-       DEBUG(5,("      srv_chal : %s\n", credstr(srv_chal->data)));
-       DEBUG(5,("      clnt+srv : %s\n", credstr(sum2)));
-       DEBUG(5,("      sess_key : %s\n", credstr(session_key)));
-}
-
-
-/****************************************************************************
-create a credential
-
-Input:
-      8 byte sesssion key
-      8 byte stored credential
-      4 byte timestamp
-
-Output:
-      8 byte credential
-****************************************************************************/
-void cred_create(uchar session_key[8], DOM_CHAL *stor_cred, UTIME timestamp, 
-                DOM_CHAL *cred)
-{
-       DOM_CHAL time_cred;
-
-       SIVAL(time_cred.data, 0, IVAL(stor_cred->data, 0) + timestamp.time);
-       SIVAL(time_cred.data, 4, IVAL(stor_cred->data, 4));
-
-       cred_hash2(cred->data, time_cred.data, session_key);
-
-       /* debug output*/
-       DEBUG(4,("cred_create\n"));
-
-       DEBUG(5,("      sess_key : %s\n", credstr(session_key)));
-       DEBUG(5,("      stor_cred: %s\n", credstr(stor_cred->data)));
-       DEBUG(5,("      timestamp: %x\n"    , timestamp.time));
-       DEBUG(5,("      timecred : %s\n", credstr(time_cred.data)));
-       DEBUG(5,("      calc_cred: %s\n", credstr(cred->data)));
-}
-
-
-/****************************************************************************
-  check a supplied credential
-
-Input:
-      8 byte received credential
-      8 byte sesssion key
-      8 byte stored credential
-      4 byte timestamp
-
-Output:
-      returns 1 if computed credential matches received credential
-      returns 0 otherwise
-****************************************************************************/
-int cred_assert(DOM_CHAL *cred, uchar session_key[8], DOM_CHAL *stored_cred,
-               UTIME timestamp)
-{
-       DOM_CHAL cred2;
-
-       cred_create(session_key, stored_cred, timestamp, &cred2);
-
-       /* debug output*/
-       DEBUG(4,("cred_assert\n"));
-
-       DEBUG(5,("      challenge : %s\n", credstr(cred->data)));
-       DEBUG(5,("      calculated: %s\n", credstr(cred2.data)));
-
-       if (memcmp(cred->data, cred2.data, 8) == 0)
-       {
-               DEBUG(5, ("credentials check ok\n"));
-               return True;
-       }
-       else
-       {
-               DEBUG(5, ("credentials check wrong\n"));
-               return False;
-       }
-}
-
-
-/****************************************************************************
-  checks credentials; generates next step in the credential chain
-****************************************************************************/
-BOOL clnt_deal_with_creds(uchar sess_key[8],
-                         DOM_CRED *sto_clnt_cred, DOM_CRED *rcv_srv_cred)
-{
-       UTIME new_clnt_time;
-       uint32 new_cred;
-
-       DEBUG(5,("clnt_deal_with_creds: %d\n", __LINE__));
-
-       /* increment client time by one second */
-       new_clnt_time.time = sto_clnt_cred->timestamp.time + 1;
-
-       /* check that the received server credentials are valid */
-       if (!cred_assert(&rcv_srv_cred->challenge, sess_key,
-                        &sto_clnt_cred->challenge, new_clnt_time))
-       {
-               return False;
-       }
-
-       /* first 4 bytes of the new seed is old client 4 bytes + clnt time + 1 */
-       new_cred = IVAL(sto_clnt_cred->challenge.data, 0);
-       new_cred += new_clnt_time.time;
-
-       /* store new seed in client credentials */
-       SIVAL(sto_clnt_cred->challenge.data, 0, new_cred);
-
-       DEBUG(5,("      new clnt cred: %s\n", credstr(sto_clnt_cred->challenge.data)));
-       return True;
-}
-
-
-/****************************************************************************
-  checks credentials; generates next step in the credential chain
-****************************************************************************/
-BOOL deal_with_creds(uchar sess_key[8],
-                    DOM_CRED *sto_clnt_cred, 
-                    DOM_CRED *rcv_clnt_cred, DOM_CRED *rtn_srv_cred)
-{
-       UTIME new_clnt_time;
-       uint32 new_cred;
-
-       DEBUG(5,("deal_with_creds: %d\n", __LINE__));
-
-       /* check that the received client credentials are valid */
-       if (!cred_assert(&rcv_clnt_cred->challenge, sess_key,
-                    &sto_clnt_cred->challenge, rcv_clnt_cred->timestamp))
-       {
-               return False;
-       }
-
-       /* increment client time by one second */
-       new_clnt_time.time = rcv_clnt_cred->timestamp.time + 1;
-
-       /* first 4 bytes of the new seed is old client 4 bytes + clnt time + 1 */
-       new_cred = IVAL(sto_clnt_cred->challenge.data, 0);
-       new_cred += new_clnt_time.time;
-
-       DEBUG(5,("deal_with_creds: new_cred[0]=%x\n", new_cred));
-
-       /* doesn't matter that server time is 0 */
-       rtn_srv_cred->timestamp.time = 0;
-
-       DEBUG(5,("deal_with_creds: new_clnt_time=%x\n", new_clnt_time.time));
-
-       /* create return credentials for inclusion in the reply */
-       cred_create(sess_key, &sto_clnt_cred->challenge, new_clnt_time,
-                   &rtn_srv_cred->challenge);
-       
-       DEBUG(5,("deal_with_creds: clnt_cred=%s\n", credstr(sto_clnt_cred->challenge.data)));
-
-       /* store new seed in client credentials */
-       SIVAL(sto_clnt_cred->challenge.data, 0, new_cred);
-
-       return True;
-}
index ceb4ad771e599648bf6477ccc4b0afdbe177d4b3..43f07684c286777113305a87e11baa85c044cb8d 100644 (file)
@@ -837,13 +837,5 @@ NTSTATUS make_pdb_methods(TALLOC_CTX *mem_ctx, PDB_METHODS **methods)
        (*methods)->update_sam_account = pdb_default_update_sam_account;
        (*methods)->delete_sam_account = pdb_default_delete_sam_account;
 
-       (*methods)->getgrsid = pdb_default_getgrsid;
-       (*methods)->getgrgid = pdb_default_getgrgid;
-       (*methods)->getgrnam = pdb_default_getgrnam;
-       (*methods)->add_group_mapping_entry = pdb_default_add_group_mapping_entry;
-       (*methods)->update_group_mapping_entry = pdb_default_update_group_mapping_entry;
-       (*methods)->delete_group_mapping_entry = pdb_default_delete_group_mapping_entry;
-       (*methods)->enum_group_mapping = pdb_default_enum_group_mapping;
-
        return NT_STATUS_OK;
 }
diff --git a/source4/printing/nt_printing.c b/source4/printing/nt_printing.c
deleted file mode 100644 (file)
index 017dade..0000000
+++ /dev/null
@@ -1,4887 +0,0 @@
-/*
- *  Unix SMB/CIFS implementation.
- *  RPC Pipe client / server routines
- *  Copyright (C) Andrew Tridgell              1992-2000,
- *  Copyright (C) Jean François Micouleau      1998-2000.
- *  Copyright (C) Gerald Carter                2002-2003.
- *
- *  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
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "includes.h"
-
-extern DOM_SID global_sid_World;
-
-static TDB_CONTEXT *tdb_forms; /* used for forms files */
-static TDB_CONTEXT *tdb_drivers; /* used for driver files */
-static TDB_CONTEXT *tdb_printers; /* used for printers files */
-
-#define FORMS_PREFIX "FORMS/"
-#define DRIVERS_PREFIX "DRIVERS/"
-#define DRIVER_INIT_PREFIX "DRIVER_INIT/"
-#define PRINTERS_PREFIX "PRINTERS/"
-#define SECDESC_PREFIX "SECDESC/"
-#define GLOBAL_C_SETPRINTER "GLOBALS/c_setprinter"
-#define NTDRIVERS_DATABASE_VERSION_1 1
-#define NTDRIVERS_DATABASE_VERSION_2 2
-#define NTDRIVERS_DATABASE_VERSION_3 3 /* little endian version of v2 */
-#define NTDRIVERS_DATABASE_VERSION NTDRIVERS_DATABASE_VERSION_3
-
-/* Map generic permissions to printer object specific permissions */
-
-GENERIC_MAPPING printer_generic_mapping = {
-       PRINTER_READ,
-       PRINTER_WRITE,
-       PRINTER_EXECUTE,
-       PRINTER_ALL_ACCESS
-};
-
-STANDARD_MAPPING printer_std_mapping = {
-       PRINTER_READ,
-       PRINTER_WRITE,
-       PRINTER_EXECUTE,
-       PRINTER_ALL_ACCESS
-};
-
-/* Map generic permissions to print server object specific permissions */
-
-GENERIC_MAPPING printserver_generic_mapping = {
-       SERVER_READ,
-       SERVER_WRITE,
-       SERVER_EXECUTE,
-       SERVER_ALL_ACCESS
-};
-
-STANDARD_MAPPING printserver_std_mapping = {
-       SERVER_READ,
-       SERVER_WRITE,
-       SERVER_EXECUTE,
-       SERVER_ALL_ACCESS
-};
-
-/* We need one default form to support our default printer. Msoft adds the
-forms it wants and in the ORDER it wants them (note: DEVMODE papersize is an
-array index). Letter is always first, so (for the current code) additions
-always put things in the correct order. */
-static const nt_forms_struct default_forms[] = {
-       {"Letter",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
-       {"Letter Small",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
-       {"Tabloid",0x1,0x44368,0x696b8,0x0,0x0,0x44368,0x696b8},
-       {"Ledger",0x1,0x696b8,0x44368,0x0,0x0,0x696b8,0x44368},
-       {"Legal",0x1,0x34b5c,0x56d10,0x0,0x0,0x34b5c,0x56d10},
-       {"Statement",0x1,0x221b4,0x34b5c,0x0,0x0,0x221b4,0x34b5c},
-       {"Executive",0x1,0x2cf56,0x411cc,0x0,0x0,0x2cf56,0x411cc},
-       {"A3",0x1,0x48828,0x668a0,0x0,0x0,0x48828,0x668a0},
-       {"A4",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
-       {"A4 Small",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
-       {"A5",0x1,0x24220,0x33450,0x0,0x0,0x24220,0x33450},
-       {"B4 (JIS)",0x1,0x3ebe8,0x58de0,0x0,0x0,0x3ebe8,0x58de0},
-       {"B5 (JIS)",0x1,0x2c6f0,0x3ebe8,0x0,0x0,0x2c6f0,0x3ebe8},
-       {"Folio",0x1,0x34b5c,0x509d8,0x0,0x0,0x34b5c,0x509d8},
-       {"Quarto",0x1,0x347d8,0x43238,0x0,0x0,0x347d8,0x43238},
-       {"10x14",0x1,0x3e030,0x56d10,0x0,0x0,0x3e030,0x56d10},
-       {"11x17",0x1,0x44368,0x696b8,0x0,0x0,0x44368,0x696b8},
-       {"Note",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
-       {"Envelope #9",0x1,0x18079,0x37091,0x0,0x0,0x18079,0x37091},
-       {"Envelope #10",0x1,0x19947,0x3ae94,0x0,0x0,0x19947,0x3ae94},
-       {"Envelope #11",0x1,0x1be7c,0x40565,0x0,0x0,0x1be7c,0x40565},
-       {"Envelope #12",0x1,0x1d74a,0x44368,0x0,0x0,0x1d74a,0x44368},
-       {"Envelope #14",0x1,0x1f018,0x47504,0x0,0x0,0x1f018,0x47504},
-       {"C size sheet",0x1,0x696b8,0x886d0,0x0,0x0,0x696b8,0x886d0},
-       {"D size sheet",0x1,0x886d0,0xd2d70,0x0,0x0,0x886d0,0xd2d70},
-       {"E size sheet",0x1,0xd2d70,0x110da0,0x0,0x0,0xd2d70,0x110da0},
-       {"Envelope DL",0x1,0x1adb0,0x35b60,0x0,0x0,0x1adb0,0x35b60},
-       {"Envelope C5",0x1,0x278d0,0x37e88,0x0,0x0,0x278d0,0x37e88},
-       {"Envelope C3",0x1,0x4f1a0,0x6fd10,0x0,0x0,0x4f1a0,0x6fd10},
-       {"Envelope C4",0x1,0x37e88,0x4f1a0,0x0,0x0,0x37e88,0x4f1a0},
-       {"Envelope C6",0x1,0x1bd50,0x278d0,0x0,0x0,0x1bd50,0x278d0},
-       {"Envelope C65",0x1,0x1bd50,0x37e88,0x0,0x0,0x1bd50,0x37e88},
-       {"Envelope B4",0x1,0x3d090,0x562e8,0x0,0x0,0x3d090,0x562e8},
-       {"Envelope B5",0x1,0x2af80,0x3d090,0x0,0x0,0x2af80,0x3d090},
-       {"Envelope B6",0x1,0x2af80,0x1e848,0x0,0x0,0x2af80,0x1e848},
-       {"Envelope",0x1,0x1adb0,0x38270,0x0,0x0,0x1adb0,0x38270},
-       {"Envelope Monarch",0x1,0x18079,0x2e824,0x0,0x0,0x18079,0x2e824},
-       {"6 3/4 Envelope",0x1,0x167ab,0x284ec,0x0,0x0,0x167ab,0x284ec},
-       {"US Std Fanfold",0x1,0x5c3e1,0x44368,0x0,0x0,0x5c3e1,0x44368},
-       {"German Std Fanfold",0x1,0x34b5c,0x4a6a0,0x0,0x0,0x34b5c,0x4a6a0},
-       {"German Legal Fanfold",0x1,0x34b5c,0x509d8,0x0,0x0,0x34b5c,0x509d8},
-       {"B4 (ISO)",0x1,0x3d090,0x562e8,0x0,0x0,0x3d090,0x562e8},
-       {"Japanese Postcard",0x1,0x186a0,0x24220,0x0,0x0,0x186a0,0x24220},
-       {"9x11",0x1,0x37cf8,0x44368,0x0,0x0,0x37cf8,0x44368},
-       {"10x11",0x1,0x3e030,0x44368,0x0,0x0,0x3e030,0x44368},
-       {"15x11",0x1,0x5d048,0x44368,0x0,0x0,0x5d048,0x44368},
-       {"Envelope Invite",0x1,0x35b60,0x35b60,0x0,0x0,0x35b60,0x35b60},
-       {"Reserved48",0x1,0x1,0x1,0x0,0x0,0x1,0x1},
-       {"Reserved49",0x1,0x1,0x1,0x0,0x0,0x1,0x1},
-       {"Letter Extra",0x1,0x3ae94,0x4a6a0,0x0,0x0,0x3ae94,0x4a6a0},
-       {"Legal Extra",0x1,0x3ae94,0x5d048,0x0,0x0,0x3ae94,0x5d048},
-       {"Tabloid Extra",0x1,0x4a6a0,0x6f9f0,0x0,0x0,0x4a6a0,0x6f9f0},
-       {"A4 Extra",0x1,0x397c2,0x4eb16,0x0,0x0,0x397c2,0x4eb16},
-       {"Letter Transverse",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
-       {"A4 Transverse",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
-       {"Letter Extra Transverse",0x1,0x3ae94,0x4a6a0,0x0,0x0,0x3ae94,0x4a6a0},
-       {"Super A",0x1,0x376b8,0x56ea0,0x0,0x0,0x376b8,0x56ea0},
-       {"Super B",0x1,0x4a768,0x76e58,0x0,0x0,0x4a768,0x76e58},
-       {"Letter Plus",0x1,0x34b5c,0x4eb16,0x0,0x0,0x34b5c,0x4eb16},
-       {"A4 Plus",0x1,0x33450,0x50910,0x0,0x0,0x33450,0x50910},
-       {"A5 Transverse",0x1,0x24220,0x33450,0x0,0x0,0x24220,0x33450},
-       {"B5 (JIS) Transverse",0x1,0x2c6f0,0x3ebe8,0x0,0x0,0x2c6f0,0x3ebe8},
-       {"A3 Extra",0x1,0x4e9d0,0x6ca48,0x0,0x0,0x4e9d0,0x6ca48},
-       {"A5 Extra",0x1,0x2a7b0,0x395f8,0x0,0x0,0x2a7b0,0x395f8},
-       {"B5 (ISO) Extra",0x1,0x31128,0x43620,0x0,0x0,0x31128,0x43620},
-       {"A2",0x1,0x668a0,0x91050,0x0,0x0,0x668a0,0x91050},
-       {"A3 Transverse",0x1,0x48828,0x668a0,0x0,0x0,0x48828,0x668a0},
-       {"A3 Extra Transverse",0x1,0x4e9d0,0x6ca48,0x0,0x0,0x4e9d0,0x6ca48},
-       {"Japanese Double Postcard",0x1,0x30d40,0x24220,0x0,0x0,0x30d40,0x24220},
-       {"A6",0x1,0x19a28,0x24220,0x0,0x0,0x19a28,0x24220},
-       {"Japanese Envelope Kaku #2",0x1,0x3a980,0x510e0,0x0,0x0,0x3a980,0x510e0},
-       {"Japanese Envelope Kaku #3",0x1,0x34bc0,0x43a08,0x0,0x0,0x34bc0,0x43a08},
-       {"Japanese Envelope Chou #3",0x1,0x1d4c0,0x395f8,0x0,0x0,0x1d4c0,0x395f8},
-       {"Japanese Envelope Chou #4",0x1,0x15f90,0x320c8,0x0,0x0,0x15f90,0x320c8},
-       {"Letter Rotated",0x1,0x44368,0x34b5c,0x0,0x0,0x44368,0x34b5c},
-       {"A3 Rotated",0x1,0x668a0,0x48828,0x0,0x0,0x668a0,0x48828},
-       {"A4 Rotated",0x1,0x48828,0x33450,0x0,0x0,0x48828,0x33450},
-       {"A5 Rotated",0x1,0x33450,0x24220,0x0,0x0,0x33450,0x24220},
-       {"B4 (JIS) Rotated",0x1,0x58de0,0x3ebe8,0x0,0x0,0x58de0,0x3ebe8},
-       {"B5 (JIS) Rotated",0x1,0x3ebe8,0x2c6f0,0x0,0x0,0x3ebe8,0x2c6f0},
-       {"Japanese Postcard Rotated",0x1,0x24220,0x186a0,0x0,0x0,0x24220,0x186a0},
-       {"Double Japan Postcard Rotated",0x1,0x24220,0x30d40,0x0,0x0,0x24220,0x30d40},
-       {"A6 Rotated",0x1,0x24220,0x19a28,0x0,0x0,0x24220,0x19a28},
-       {"Japan Envelope Kaku #2 Rotated",0x1,0x510e0,0x3a980,0x0,0x0,0x510e0,0x3a980},
-       {"Japan Envelope Kaku #3 Rotated",0x1,0x43a08,0x34bc0,0x0,0x0,0x43a08, 0x34bc0},
-       {"Japan Envelope Chou #3 Rotated",0x1,0x395f8,0x1d4c0,0x0,0x0,0x395f8,0x1d4c0},
-       {"Japan Envelope Chou #4 Rotated",0x1,0x320c8,0x15f90,0x0,0x0,0x320c8,0x15f90},
-       {"B6 (JIS)",0x1,0x1f400,0x2c6f0,0x0,0x0,0x1f400,0x2c6f0},
-       {"B6 (JIS) Rotated",0x1,0x2c6f0,0x1f400,0x0,0x0,0x2c6f0,0x1f400},
-       {"12x11",0x1,0x4a724,0x443e1,0x0,0x0,0x4a724,0x443e1},
-       {"Japan Envelope You #4",0x1,0x19a28,0x395f8,0x0,0x0,0x19a28,0x395f8},
-       {"Japan Envelope You #4 Rotated",0x1,0x395f8,0x19a28,0x0,0x0,0x395f8,0x19a28},
-       {"PRC 16K",0x1,0x2de60,0x3f7a0,0x0,0x0,0x2de60,0x3f7a0},
-       {"PRC 32K",0x1,0x1fbd0,0x2cec0,0x0,0x0,0x1fbd0,0x2cec0},
-       {"PRC 32K(Big)",0x1,0x222e0,0x318f8,0x0,0x0,0x222e0,0x318f8},
-       {"PRC Envelope #1",0x1,0x18e70,0x28488,0x0,0x0,0x18e70,0x28488},
-       {"PRC Envelope #2",0x1,0x18e70,0x2af80,0x0,0x0,0x18e70,0x2af80},
-       {"PRC Envelope #3",0x1,0x1e848,0x2af80,0x0,0x0,0x1e848,0x2af80},
-       {"PRC Envelope #4",0x1,0x1adb0,0x32c80,0x0,0x0,0x1adb0,0x32c80},
-       {"PRC Envelope #5",0x1,0x1adb0,0x35b60,0x0,0x0,0x1adb0,0x35b60},
-       {"PRC Envelope #6",0x1,0x1d4c0,0x38270,0x0,0x0,0x1d4c0,0x38270},
-       {"PRC Envelope #7",0x1,0x27100,0x38270,0x0,0x0,0x27100,0x38270},
-       {"PRC Envelope #8",0x1,0x1d4c0,0x4b708,0x0,0x0,0x1d4c0,0x4b708},
-       {"PRC Envelope #9",0x1,0x37e88,0x4f1a0,0x0,0x0,0x37e88,0x4f1a0},
-       {"PRC Envelope #10",0x1,0x4f1a0,0x6fd10,0x0,0x0,0x4f1a0,0x6fd10},
-       {"PRC 16K Rotated",0x1,0x3f7a0,0x2de60,0x0,0x0,0x3f7a0,0x2de60},
-       {"PRC 32K Rotated",0x1,0x2cec0,0x1fbd0,0x0,0x0,0x2cec0,0x1fbd0},
-       {"PRC 32K(Big) Rotated",0x1,0x318f8,0x222e0,0x0,0x0,0x318f8,0x222e0},
-       {"PRC Envelope #1 Rotated",0x1,0x28488,0x18e70,0x0,0x0,0x28488,0x18e70},
-       {"PRC Envelope #2 Rotated",0x1,0x2af80,0x18e70,0x0,0x0,0x2af80,0x18e70},
-       {"PRC Envelope #3 Rotated",0x1,0x2af80,0x1e848,0x0,0x0,0x2af80,0x1e848},
-       {"PRC Envelope #4 Rotated",0x1,0x32c80,0x1adb0,0x0,0x0,0x32c80,0x1adb0},
-       {"PRC Envelope #5 Rotated",0x1,0x35b60,0x1adb0,0x0,0x0,0x35b60,0x1adb0},
-       {"PRC Envelope #6 Rotated",0x1,0x38270,0x1d4c0,0x0,0x0,0x38270,0x1d4c0},
-       {"PRC Envelope #7 Rotated",0x1,0x38270,0x27100,0x0,0x0,0x38270,0x27100},
-       {"PRC Envelope #8 Rotated",0x1,0x4b708,0x1d4c0,0x0,0x0,0x4b708,0x1d4c0},
-       {"PRC Envelope #9 Rotated",0x1,0x4f1a0,0x37e88,0x0,0x0,0x4f1a0,0x37e88},
-       {"PRC Envelope #10 Rotated",0x1,0x6fd10,0x4f1a0,0x0,0x0,0x6fd10,0x4f1a0}
-};
-
-static BOOL upgrade_to_version_3(void)
-{
-       TDB_DATA kbuf, newkey, dbuf;
-       DEBUG(0,("upgrade_to_version_3: upgrading print tdb's to version 3\n"));
-       for (kbuf = tdb_firstkey(tdb_drivers); kbuf.dptr;
-                       newkey = tdb_nextkey(tdb_drivers, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
-
-               dbuf = tdb_fetch(tdb_drivers, kbuf);
-
-               if (strncmp(kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) {
-                       DEBUG(0,("upgrade_to_version_3:moving form\n"));
-                       if (tdb_store(tdb_forms, kbuf, dbuf, TDB_REPLACE) != 0) {
-                               SAFE_FREE(dbuf.dptr);
-                               DEBUG(0,("upgrade_to_version_3: failed to move form. Error (%s).\n", tdb_errorstr(tdb_forms)));
-                               return False;
-                       }
-                       if (tdb_delete(tdb_drivers, kbuf) != 0) {
-                               SAFE_FREE(dbuf.dptr);
-                               DEBUG(0,("upgrade_to_version_3: failed to delete form. Error (%s)\n", tdb_errorstr(tdb_drivers)));
-                               return False;
-                       }
-               }
-               if (strncmp(kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) {
-                       DEBUG(0,("upgrade_to_version_3:moving printer\n"));
-                       if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {
-                               SAFE_FREE(dbuf.dptr);
-                               DEBUG(0,("upgrade_to_version_3: failed to move printer. Error (%s)\n", tdb_errorstr(tdb_printers)));
-                               return False;
-                       }
-                       if (tdb_delete(tdb_drivers, kbuf) != 0) {
-                               SAFE_FREE(dbuf.dptr);
-                               DEBUG(0,("upgrade_to_version_3: failed to delete printer. Error (%s)\n", tdb_errorstr(tdb_drivers)));
-                               return False;
-                       }
-               }
-               if (strncmp(kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) {
-                       DEBUG(0,("upgrade_to_version_3:moving secdesc\n"));
-                       if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {
-                               SAFE_FREE(dbuf.dptr);
-                               DEBUG(0,("upgrade_to_version_3: failed to move secdesc. Error (%s)\n", tdb_errorstr(tdb_printers)));
-                               return False;
-                       }
-                       if (tdb_delete(tdb_drivers, kbuf) != 0) {
-                               SAFE_FREE(dbuf.dptr);
-                               DEBUG(0,("upgrade_to_version_3: failed to delete secdesc. Error (%s)\n", tdb_errorstr(tdb_drivers)));
-                               return False;
-                       }
-               }
-               SAFE_FREE(dbuf.dptr);
-       }
-
-       return True;
-}
-
-/****************************************************************************
- Open the NT printing tdbs. Done once before fork().
-****************************************************************************/
-
-BOOL nt_printing_init(void)
-{
-       static pid_t local_pid;
-       const char *vstring = "INFO/version";
-
-       if (tdb_drivers && tdb_printers && tdb_forms && local_pid == sys_getpid())
-               return True;
-       if (tdb_drivers)
-               tdb_close(tdb_drivers);
-       tdb_drivers = tdb_open_log(lock_path("ntdrivers.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
-       if (!tdb_drivers) {
-               DEBUG(0,("nt_printing_init: Failed to open nt drivers database %s (%s)\n",
-                       lock_path("ntdrivers.tdb"), strerror(errno) ));
-               return False;
-       }
-       if (tdb_printers)
-               tdb_close(tdb_printers);
-       tdb_printers = tdb_open_log(lock_path("ntprinters.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
-       if (!tdb_printers) {
-               DEBUG(0,("nt_printing_init: Failed to open nt printers database %s (%s)\n",
-                       lock_path("ntprinters.tdb"), strerror(errno) ));
-               return False;
-       }
-       if (tdb_forms)
-               tdb_close(tdb_forms);
-       tdb_forms = tdb_open_log(lock_path("ntforms.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
-       if (!tdb_forms) {
-               DEBUG(0,("nt_printing_init: Failed to open nt forms database %s (%s)\n",
-                       lock_path("ntforms.tdb"), strerror(errno) ));
-               return False;
-       }
-       local_pid = sys_getpid();
-       /* handle a Samba upgrade */
-       tdb_lock_bystring(tdb_drivers, vstring, 0);
-       {
-               int32 vers_id;
-
-               /* Cope with byte-reversed older versions of the db. */
-               vers_id = tdb_fetch_int32(tdb_drivers, vstring);
-               if ((vers_id == NTDRIVERS_DATABASE_VERSION_2) || (IREV(vers_id) == NTDRIVERS_DATABASE_VERSION_2)) {
-                       /* Written on a bigendian machine with old fetch_int code. Save as le. */
-                       /* The only upgrade between V2 and V3 is to save the version in little-endian. */
-                       tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION);
-                       vers_id = NTDRIVERS_DATABASE_VERSION;
-               }
-
-               if (vers_id != NTDRIVERS_DATABASE_VERSION) {
-
-                       if ((vers_id == NTDRIVERS_DATABASE_VERSION_1) || (IREV(vers_id) == NTDRIVERS_DATABASE_VERSION_1)) { 
-                               if (!upgrade_to_version_3())
-                                       return False;
-                       } else
-                               tdb_traverse(tdb_drivers, tdb_traverse_delete_fn, NULL);
-                        
-                       tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION);
-               }
-       }
-       tdb_unlock_bystring(tdb_drivers, vstring);
-
-       update_c_setprinter(True);
-
-       /*
-        * register callback to handle updating printers as new
-        * drivers are installed
-        */
-
-       message_register( MSG_PRINTER_DRVUPGRADE, do_drv_upgrade_printer );
-
-       /*
-        * register callback to handle updating printer data
-        * when a driver is initialized
-        */
-
-       message_register( MSG_PRINTERDATA_INIT_RESET, reset_all_printerdata );
-
-
-       return True;
-}
-
-/*******************************************************************
- tdb traversal function for counting printers.
-********************************************************************/
-
-static int traverse_counting_printers(TDB_CONTEXT *t, TDB_DATA key,
-                                      TDB_DATA data, void *context)
-{
-       int *printer_count = (int*)context;
-       if (memcmp(PRINTERS_PREFIX, key.dptr, sizeof(PRINTERS_PREFIX)-1) == 0) {
-               (*printer_count)++;
-               DEBUG(10,("traverse_counting_printers: printer = [%s]  printer_count = %d\n", key.dptr, *printer_count));
-       }
-       return 0;
-}
-/*******************************************************************
- Update the spooler global c_setprinter. This variable is initialized
- when the parent smbd starts with the number of existing printers. It
- is monotonically increased by the current number of printers *after*
- each add or delete printer RPC. Only Microsoft knows why... JRR020119
-********************************************************************/
-
-uint32 update_c_setprinter(BOOL initialize)
-{
-       int32 c_setprinter;
-       int32 printer_count = 0;
-       tdb_lock_bystring(tdb_printers, GLOBAL_C_SETPRINTER, 0);
-       /* Traverse the tdb, counting the printers */
-       tdb_traverse(tdb_printers, traverse_counting_printers, (void *)&printer_count);
-       /* If initializing, set c_setprinter to current printers count
-        * otherwise, bump it by the current printer count
-        */
-       if (!initialize)
-               c_setprinter = tdb_fetch_int32(tdb_printers, GLOBAL_C_SETPRINTER) + printer_count;
-       else
-               c_setprinter = printer_count;
-       DEBUG(10,("update_c_setprinter: c_setprinter = %u\n", (unsigned int)c_setprinter));
-       tdb_store_int32(tdb_printers, GLOBAL_C_SETPRINTER, c_setprinter);
-       tdb_unlock_bystring(tdb_printers, GLOBAL_C_SETPRINTER);
-       return (uint32)c_setprinter;
-}
-
-/*******************************************************************
- Get the spooler global c_setprinter, accounting for initialization.
-********************************************************************/
-
-uint32 get_c_setprinter(void)
-{
-       int32 c_setprinter = tdb_fetch_int32(tdb_printers, GLOBAL_C_SETPRINTER);
-       if (c_setprinter == (int32)-1)
-               c_setprinter = update_c_setprinter(True);
-       DEBUG(10,("get_c_setprinter: c_setprinter = %d\n", c_setprinter));
-       return (uint32)c_setprinter;
-}
-
-/****************************************************************************
- Get builtin form struct list.
-****************************************************************************/
-
-int get_builtin_ntforms(nt_forms_struct **list)
-{
-       *list = (nt_forms_struct *)memdup(&default_forms[0], sizeof(default_forms));
-       return sizeof(default_forms) / sizeof(default_forms[0]);
-}
-
-/****************************************************************************
- get a builtin form struct
-****************************************************************************/
-
-BOOL get_a_builtin_ntform(UNISTR2 *uni_formname,nt_forms_struct *form)
-{
-       int i,count;
-       fstring form_name;
-       unistr2_to_ascii(form_name, uni_formname, sizeof(form_name)-1);
-       DEBUGADD(6,("Looking for builtin form %s \n", form_name));
-       count = sizeof(default_forms) / sizeof(default_forms[0]);
-       for (i=0;i<count;i++) {
-               if (strequal(form_name,default_forms[i].name)) {
-                       DEBUGADD(6,("Found builtin form %s \n", form_name));
-                       memcpy(form,&default_forms[i],sizeof(*form));
-                       break;
-               }
-       }
-
-       return (i !=count);
-}
-
-/****************************************************************************
-get a form struct list
-****************************************************************************/
-int get_ntforms(nt_forms_struct **list)
-{
-       TDB_DATA kbuf, newkey, dbuf;
-       nt_forms_struct *tl;
-       nt_forms_struct form;
-       int ret;
-       int i;
-       int n = 0;
-
-       for (kbuf = tdb_firstkey(tdb_forms);
-            kbuf.dptr;
-            newkey = tdb_nextkey(tdb_forms, kbuf), safe_free(kbuf.dptr), kbuf=newkey) 
-       {
-               if (strncmp(kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) != 0) 
-                       continue;
-               
-               dbuf = tdb_fetch(tdb_forms, kbuf);
-               if (!dbuf.dptr) 
-                       continue;
-
-               fstrcpy(form.name, kbuf.dptr+strlen(FORMS_PREFIX));
-               ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "dddddddd",
-                                &i, &form.flag, &form.width, &form.length, &form.left,
-                                &form.top, &form.right, &form.bottom);
-               SAFE_FREE(dbuf.dptr);
-               if (ret != dbuf.dsize) 
-                       continue;
-
-               tl = Realloc(*list, sizeof(nt_forms_struct)*(n+1));
-               if (!tl) {
-                       DEBUG(0,("get_ntforms: Realloc fail.\n"));
-                       return 0;
-               }
-               *list = tl;
-               (*list)[n] = form;
-               n++;
-       }
-       
-
-       return n;
-}
-
-/****************************************************************************
-write a form struct list
-****************************************************************************/
-int write_ntforms(nt_forms_struct **list, int number)
-{
-       pstring buf, key;
-       int len;
-       TDB_DATA kbuf,dbuf;
-       int i;
-
-       for (i=0;i<number;i++) {
-               /* save index, so list is rebuilt in correct order */
-               len = tdb_pack(buf, sizeof(buf), "dddddddd",
-                              i, (*list)[i].flag, (*list)[i].width, (*list)[i].length,
-                              (*list)[i].left, (*list)[i].top, (*list)[i].right,
-                              (*list)[i].bottom);
-               if (len > sizeof(buf)) break;
-               slprintf(key, sizeof(key)-1, "%s%s", FORMS_PREFIX, (*list)[i].name);
-               kbuf.dsize = strlen(key)+1;
-               kbuf.dptr = key;
-               dbuf.dsize = len;
-               dbuf.dptr = buf;
-               if (tdb_store(tdb_forms, kbuf, dbuf, TDB_REPLACE) != 0) break;
-       }
-
-       return i;
-}
-
-/****************************************************************************
-add a form struct at the end of the list
-****************************************************************************/
-BOOL add_a_form(nt_forms_struct **list, const FORM *form, int *count)
-{
-       int n=0;
-       BOOL update;
-       fstring form_name;
-       nt_forms_struct *tl;
-
-       /*
-        * NT tries to add forms even when
-        * they are already in the base
-        * only update the values if already present
-        */
-
-       update=False;
-       
-       unistr2_to_ascii(form_name, &form->name, sizeof(form_name)-1);
-       for (n=0; n<*count; n++) {
-               if (!strncmp((*list)[n].name, form_name, strlen(form_name))) {
-                       DEBUG(103, ("NT workaround, [%s] already exists\n", form_name));
-                       update=True;
-                       break;
-               }
-       }
-
-       if (update==False) {
-               if((tl=Realloc(*list, (n+1)*sizeof(nt_forms_struct))) == NULL) {
-                       DEBUG(0,("add_a_form: failed to enlarge forms list!\n"));
-                       return False;
-               }
-               *list = tl;
-               unistr2_to_ascii((*list)[n].name, &form->name, sizeof((*list)[n].name)-1);
-               (*count)++;
-       }
-       
-       (*list)[n].flag=form->flags;
-       (*list)[n].width=form->size_x;
-       (*list)[n].length=form->size_y;
-       (*list)[n].left=form->left;
-       (*list)[n].top=form->top;
-       (*list)[n].right=form->right;
-       (*list)[n].bottom=form->bottom;
-
-       return True;
-}
-
-/****************************************************************************
- Delete a named form struct.
-****************************************************************************/
-
-BOOL delete_a_form(nt_forms_struct **list, UNISTR2 *del_name, int *count, WERROR *ret)
-{
-       pstring key;
-       TDB_DATA kbuf;
-       int n=0;
-       fstring form_name;
-
-       *ret = WERR_OK;
-
-       unistr2_to_ascii(form_name, del_name, sizeof(form_name)-1);
-
-       for (n=0; n<*count; n++) {
-               if (!strncmp((*list)[n].name, form_name, strlen(form_name))) {
-                       DEBUG(103, ("delete_a_form, [%s] in list\n", form_name));
-                       break;
-               }
-       }
-
-       if (n == *count) {
-               DEBUG(10,("delete_a_form, [%s] not found\n", form_name));
-               *ret = WERR_INVALID_PARAM;
-               return False;
-       }
-
-       slprintf(key, sizeof(key)-1, "%s%s", FORMS_PREFIX, (*list)[n].name);
-       kbuf.dsize = strlen(key)+1;
-       kbuf.dptr = key;
-       if (tdb_delete(tdb_forms, kbuf) != 0) {
-               *ret = WERR_NOMEM;
-               return False;
-       }
-
-       return True;
-}
-
-/****************************************************************************
- Update a form struct.
-****************************************************************************/
-
-void update_a_form(nt_forms_struct **list, const FORM *form, int count)
-{
-       int n=0;
-       fstring form_name;
-       unistr2_to_ascii(form_name, &(form->name), sizeof(form_name)-1);
-
-       DEBUG(106, ("[%s]\n", form_name));
-       for (n=0; n<count; n++) {
-               DEBUGADD(106, ("n [%d]:[%s]\n", n, (*list)[n].name));
-               if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
-                       break;
-       }
-
-       if (n==count) return;
-
-       (*list)[n].flag=form->flags;
-       (*list)[n].width=form->size_x;
-       (*list)[n].length=form->size_y;
-       (*list)[n].left=form->left;
-       (*list)[n].top=form->top;
-       (*list)[n].right=form->right;
-       (*list)[n].bottom=form->bottom;
-}
-
-/****************************************************************************
- Get the nt drivers list.
- Traverse the database and look-up the matching names.
-****************************************************************************/
-int get_ntdrivers(fstring **list, const char *architecture, uint32 version)
-{
-       int total=0;
-       fstring short_archi;
-       fstring *fl;
-       pstring key;
-       TDB_DATA kbuf, newkey;
-
-       get_short_archi(short_archi, architecture);
-       slprintf(key, sizeof(key)-1, "%s%s/%d/", DRIVERS_PREFIX, short_archi, version);
-
-       for (kbuf = tdb_firstkey(tdb_drivers);
-            kbuf.dptr;
-            newkey = tdb_nextkey(tdb_drivers, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
-
-               if (strncmp(kbuf.dptr, key, strlen(key)) != 0)
-                       continue;
-               
-               if((fl = Realloc(*list, sizeof(fstring)*(total+1))) == NULL) {
-                       DEBUG(0,("get_ntdrivers: failed to enlarge list!\n"));
-                       return -1;
-               }
-               else *list = fl;
-
-               fstrcpy((*list)[total], kbuf.dptr+strlen(key));
-               total++;
-       }
-
-       return(total);
-}
-
-/****************************************************************************
- Function to do the mapping between the long architecture name and
- the short one.
-****************************************************************************/
-BOOL get_short_archi(char *short_archi, const char *long_archi)
-{
-       struct table {
-               const char *long_archi;
-               const char *short_archi;
-       };
-       
-       struct table archi_table[]=
-       {
-               {"Windows 4.0",          "WIN40"    },
-               {"Windows NT x86",       "W32X86"   },
-               {"Windows NT R4000",     "W32MIPS"  },
-               {"Windows NT Alpha_AXP", "W32ALPHA" },
-               {"Windows NT PowerPC",   "W32PPC"   },
-               {NULL,                   ""         }
-       };
-       
-       int i=-1;
-
-       DEBUG(107,("Getting architecture dependant directory\n"));
-
-       if (long_archi == NULL) {
-               DEBUGADD(107,("Bad long_archi param.!\n"));
-               return False;
-       }
-
-       do {
-               i++;
-       } while ( (archi_table[i].long_archi!=NULL ) &&
-                 StrCaseCmp(long_archi, archi_table[i].long_archi) );
-
-       if (archi_table[i].long_archi==NULL) {
-               DEBUGADD(107,("Unknown architecture [%s] !\n", long_archi));
-               return False;
-       }
-
-       StrnCpy (short_archi, archi_table[i].short_archi, strlen(archi_table[i].short_archi));
-
-       DEBUGADD(108,("index: [%d]\n", i));
-       DEBUGADD(108,("long architecture: [%s]\n", long_archi));
-       DEBUGADD(108,("short architecture: [%s]\n", short_archi));
-       
-       return True;
-}
-
-/****************************************************************************
- Version information in Microsoft files is held in a VS_VERSION_INFO structure.
- There are two case to be covered here: PE (Portable Executable) and NE (New
- Executable) files. Both files support the same INFO structure, but PE files
- store the signature in unicode, and NE files store it as !unicode.
- returns -1 on error, 1 on version info found, and 0 on no version info found.
-****************************************************************************/
-
-static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32 *minor)
-{
-       int     i;
-       char    *buf;
-       ssize_t byte_count;
-
-       if ((buf=malloc(PE_HEADER_SIZE)) == NULL) {
-               DEBUG(0,("get_file_version: PE file [%s] PE Header malloc failed bytes = %d\n",
-                               fname, PE_HEADER_SIZE));
-               goto error_exit;
-       }
-
-       /* Note: DOS_HEADER_SIZE < malloc'ed PE_HEADER_SIZE */
-       if ((byte_count = vfs_read_data(fsp, buf, DOS_HEADER_SIZE)) < DOS_HEADER_SIZE) {
-               DEBUG(3,("get_file_version: File [%s] DOS header too short, bytes read = %d\n",
-                               fname, byte_count));
-               goto no_version_info;
-       }
-
-       /* Is this really a DOS header? */
-       if (SVAL(buf,DOS_HEADER_MAGIC_OFFSET) != DOS_HEADER_MAGIC) {
-               DEBUG(6,("get_file_version: File [%s] bad DOS magic = 0x%x\n",
-                               fname, SVAL(buf,DOS_HEADER_MAGIC_OFFSET)));
-               goto no_version_info;
-       }
-
-       /* Skip OEM header (if any) and the DOS stub to start of Windows header */
-       if (fsp->conn->vfs_ops.lseek(fsp, fsp->fd, SVAL(buf,DOS_HEADER_LFANEW_OFFSET), SEEK_SET) == (SMB_OFF_T)-1) {
-               DEBUG(3,("get_file_version: File [%s] too short, errno = %d\n",
-                               fname, errno));
-               /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
-               goto no_version_info;
-       }
-
-       if ((byte_count = vfs_read_data(fsp, buf, PE_HEADER_SIZE)) < PE_HEADER_SIZE) {
-               DEBUG(3,("get_file_version: File [%s] Windows header too short, bytes read = %d\n",
-                               fname, byte_count));
-               /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
-               goto no_version_info;
-       }
-
-       /* The header may be a PE (Portable Executable) or an NE (New Executable) */
-       if (IVAL(buf,PE_HEADER_SIGNATURE_OFFSET) == PE_HEADER_SIGNATURE) {
-               int num_sections;
-               int section_table_bytes;
-               
-               if (SVAL(buf,PE_HEADER_MACHINE_OFFSET) != PE_HEADER_MACHINE_I386) {
-                       DEBUG(3,("get_file_version: PE file [%s] wrong machine = 0x%x\n",
-                                       fname, SVAL(buf,PE_HEADER_MACHINE_OFFSET)));
-                       /* At this point, we assume the file is in error. It still could be somthing
-                        * else besides a PE file, but it unlikely at this point.
-                        */
-                       goto error_exit;
-               }
-
-               /* get the section table */
-               num_sections        = SVAL(buf,PE_HEADER_NUMBER_OF_SECTIONS);
-               section_table_bytes = num_sections * PE_HEADER_SECT_HEADER_SIZE;
-               SAFE_FREE(buf);
-               if ((buf=malloc(section_table_bytes)) == NULL) {
-                       DEBUG(0,("get_file_version: PE file [%s] section table malloc failed bytes = %d\n",
-                                       fname, section_table_bytes));
-                       goto error_exit;
-               }
-
-               if ((byte_count = vfs_read_data(fsp, buf, section_table_bytes)) < section_table_bytes) {
-                       DEBUG(3,("get_file_version: PE file [%s] Section header too short, bytes read = %d\n",
-                                       fname, byte_count));
-                       goto error_exit;
-               }
-
-               /* Iterate the section table looking for the resource section ".rsrc" */
-               for (i = 0; i < num_sections; i++) {
-                       int sec_offset = i * PE_HEADER_SECT_HEADER_SIZE;
-
-                       if (strcmp(".rsrc", &buf[sec_offset+PE_HEADER_SECT_NAME_OFFSET]) == 0) {
-                               int section_pos   = IVAL(buf,sec_offset+PE_HEADER_SECT_PTR_DATA_OFFSET);
-                               int section_bytes = IVAL(buf,sec_offset+PE_HEADER_SECT_SIZE_DATA_OFFSET);
-
-                               SAFE_FREE(buf);
-                               if ((buf=malloc(section_bytes)) == NULL) {
-                                       DEBUG(0,("get_file_version: PE file [%s] version malloc failed bytes = %d\n",
-                                                       fname, section_bytes));
-                                       goto error_exit;
-                               }
-
-                               /* Seek to the start of the .rsrc section info */
-                               if (fsp->conn->vfs_ops.lseek(fsp, fsp->fd, section_pos, SEEK_SET) == (SMB_OFF_T)-1) {
-                                       DEBUG(3,("get_file_version: PE file [%s] too short for section info, errno = %d\n",
-                                                       fname, errno));
-                                       goto error_exit;
-                               }
-
-                               if ((byte_count = vfs_read_data(fsp, buf, section_bytes)) < section_bytes) {
-                                       DEBUG(3,("get_file_version: PE file [%s] .rsrc section too short, bytes read = %d\n",
-                                                       fname, byte_count));
-                                       goto error_exit;
-                               }
-
-                               for (i=0; i<section_bytes-VS_VERSION_INFO_UNICODE_SIZE; i++) {
-                                       /* Scan for 1st 3 unicoded bytes followed by word aligned magic value */
-                                       if (buf[i] == 'V' && buf[i+1] == '\0' && buf[i+2] == 'S') {
-                                               /* Align to next long address */
-                                               int pos = (i + sizeof(VS_SIGNATURE)*2 + 3) & 0xfffffffc;
-
-                                               if (IVAL(buf,pos) == VS_MAGIC_VALUE) {
-                                                       *major = IVAL(buf,pos+VS_MAJOR_OFFSET);
-                                                       *minor = IVAL(buf,pos+VS_MINOR_OFFSET);
-                                                       
-                                                       DEBUG(6,("get_file_version: PE file [%s] Version = %08x:%08x (%d.%d.%d.%d)\n",
-                                                                         fname, *major, *minor,
-                                                                         (*major>>16)&0xffff, *major&0xffff,
-                                                                         (*minor>>16)&0xffff, *minor&0xffff));
-                                                       SAFE_FREE(buf);
-                                                       return 1;
-                                               }
-                                       }
-                               }
-                       }
-               }
-
-               /* Version info not found, fall back to origin date/time */
-               DEBUG(10,("get_file_version: PE file [%s] has no version info\n", fname));
-               SAFE_FREE(buf);
-               return 0;
-
-       } else if (SVAL(buf,NE_HEADER_SIGNATURE_OFFSET) == NE_HEADER_SIGNATURE) {
-               if (CVAL(buf,NE_HEADER_TARGET_OS_OFFSET) != NE_HEADER_TARGOS_WIN ) {
-                       DEBUG(3,("get_file_version: NE file [%s] wrong target OS = 0x%x\n",
-                                       fname, CVAL(buf,NE_HEADER_TARGET_OS_OFFSET)));
-                       /* At this point, we assume the file is in error. It still could be somthing
-                        * else besides a NE file, but it unlikely at this point. */
-                       goto error_exit;
-               }
-
-               /* Allocate a bit more space to speed up things */
-               SAFE_FREE(buf);
-               if ((buf=malloc(VS_NE_BUF_SIZE)) == NULL) {
-                       DEBUG(0,("get_file_version: NE file [%s] malloc failed bytes  = %d\n",
-                                       fname, PE_HEADER_SIZE));
-                       goto error_exit;
-               }
-
-               /* This is a HACK! I got tired of trying to sort through the messy
-                * 'NE' file format. If anyone wants to clean this up please have at
-                * it, but this works. 'NE' files will eventually fade away. JRR */
-               while((byte_count = vfs_read_data(fsp, buf, VS_NE_BUF_SIZE)) > 0) {
-                       /* Cover case that should not occur in a well formed 'NE' .dll file */
-                       if (byte_count-VS_VERSION_INFO_SIZE <= 0) break;
-
-                       for(i=0; i<byte_count; i++) {
-                               /* Fast skip past data that can't possibly match */
-                               if (buf[i] != 'V') continue;
-
-                               /* Potential match data crosses buf boundry, move it to beginning
-                                * of buf, and fill the buf with as much as it will hold. */
-                               if (i>byte_count-VS_VERSION_INFO_SIZE) {
-                                       int bc;
-
-                                       memcpy(buf, &buf[i], byte_count-i);
-                                       if ((bc = vfs_read_data(fsp, &buf[byte_count-i], VS_NE_BUF_SIZE-
-                                                                  (byte_count-i))) < 0) {
-
-                                               DEBUG(0,("get_file_version: NE file [%s] Read error, errno=%d\n",
-                                                                fname, errno));
-                                               goto error_exit;
-                                       }
-
-                                       byte_count = bc + (byte_count - i);
-                                       if (byte_count<VS_VERSION_INFO_SIZE) break;
-
-                                       i = 0;
-                               }
-
-                               /* Check that the full signature string and the magic number that
-                                * follows exist (not a perfect solution, but the chances that this
-                                * occurs in code is, well, remote. Yes I know I'm comparing the 'V'
-                                * twice, as it is simpler to read the code. */
-                               if (strcmp(&buf[i], VS_SIGNATURE) == 0) {
-                                       /* Compute skip alignment to next long address */
-                                       int skip = -(fsp->conn->vfs_ops.lseek(fsp, fsp->fd, 0, SEEK_CUR) - (byte_count - i) +
-                                                                sizeof(VS_SIGNATURE)) & 3;
-                                       if (IVAL(buf,i+sizeof(VS_SIGNATURE)+skip) != 0xfeef04bd) continue;
-
-                                       *major = IVAL(buf,i+sizeof(VS_SIGNATURE)+skip+VS_MAJOR_OFFSET);
-                                       *minor = IVAL(buf,i+sizeof(VS_SIGNATURE)+skip+VS_MINOR_OFFSET);
-                                       DEBUG(6,("get_file_version: NE file [%s] Version = %08x:%08x (%d.%d.%d.%d)\n",
-                                                         fname, *major, *minor,
-                                                         (*major>>16)&0xffff, *major&0xffff,
-                                                         (*minor>>16)&0xffff, *minor&0xffff));
-                                       SAFE_FREE(buf);
-                                       return 1;
-                               }
-                       }
-               }
-
-               /* Version info not found, fall back to origin date/time */
-               DEBUG(0,("get_file_version: NE file [%s] Version info not found\n", fname));
-               SAFE_FREE(buf);
-               return 0;
-
-       } else
-               /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
-               DEBUG(3,("get_file_version: File [%s] unknown file format, signature = 0x%x\n",
-                               fname, IVAL(buf,PE_HEADER_SIGNATURE_OFFSET)));
-
-       no_version_info:
-               SAFE_FREE(buf);
-               return 0;
-
-       error_exit:
-               SAFE_FREE(buf);
-               return -1;
-}
-
-/****************************************************************************
-Drivers for Microsoft systems contain multiple files. Often, multiple drivers
-share one or more files. During the MS installation process files are checked
-to insure that only a newer version of a shared file is installed over an
-older version. There are several possibilities for this comparison. If there
-is no previous version, the new one is newer (obviously). If either file is
-missing the version info structure, compare the creation date (on Unix use
-the modification date). Otherwise chose the numerically larger version number.
-****************************************************************************/
-
-static int file_version_is_newer(struct tcon_context *conn, fstring new_file, fstring old_file)
-{
-       BOOL   use_version = True;
-       pstring filepath;
-
-       uint32 new_major;
-       uint32 new_minor;
-       time_t new_create_time;
-
-       uint32 old_major;
-       uint32 old_minor;
-       time_t old_create_time;
-
-       int access_mode;
-       int action;
-       files_struct    *fsp = NULL;
-       SMB_STRUCT_STAT st;
-       SMB_STRUCT_STAT stat_buf;
-       BOOL bad_path;
-
-       ZERO_STRUCT(st);
-       ZERO_STRUCT(stat_buf);
-       new_create_time = (time_t)0;
-       old_create_time = (time_t)0;
-
-       /* Get file version info (if available) for previous file (if it exists) */
-       pstrcpy(filepath, old_file);
-
-       unix_convert(filepath,conn,NULL,&bad_path,&stat_buf);
-
-       fsp = open_file_shared(conn, filepath, &stat_buf,
-                                                  SET_OPEN_MODE(DOS_OPEN_RDONLY),
-                                                  (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
-                                                  0, 0, &access_mode, &action);
-       if (!fsp) {
-               /* Old file not found, so by definition new file is in fact newer */
-               DEBUG(10,("file_version_is_newer: Can't open old file [%s], errno = %d\n",
-                               filepath, errno));
-               return True;
-
-       } else {
-               int ret = get_file_version(fsp, old_file, &old_major, &old_minor);
-               if (ret == -1) goto error_exit;
-
-               if (!ret) {
-                       DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
-                                        old_file));
-                       use_version = False;
-                       if (fsp->conn->vfs_ops.fstat(fsp, fsp->fd, &st) == -1) goto error_exit;
-                       old_create_time = st.st_mtime;
-                       DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", old_create_time));
-               }
-       }
-       close_file(fsp, True);
-
-       /* Get file version info (if available) for new file */
-       pstrcpy(filepath, new_file);
-       unix_convert(filepath,conn,NULL,&bad_path,&stat_buf);
-
-       fsp = open_file_shared(conn, filepath, &stat_buf,
-                                                  SET_OPEN_MODE(DOS_OPEN_RDONLY),
-                                                  (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
-                                                  0, 0, &access_mode, &action);
-       if (!fsp) {
-               /* New file not found, this shouldn't occur if the caller did its job */
-               DEBUG(3,("file_version_is_newer: Can't open new file [%s], errno = %d\n",
-                               filepath, errno));
-               goto error_exit;
-
-       } else {
-               int ret = get_file_version(fsp, new_file, &new_major, &new_minor);
-               if (ret == -1) goto error_exit;
-
-               if (!ret) {
-                       DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
-                                        new_file));
-                       use_version = False;
-                       if (fsp->conn->vfs_ops.fstat(fsp, fsp->fd, &st) == -1) goto error_exit;
-                       new_create_time = st.st_mtime;
-                       DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", new_create_time));
-               }
-       }
-       close_file(fsp, True);
-
-       if (use_version && (new_major != old_major || new_minor != old_minor)) {
-               /* Compare versions and choose the larger version number */
-               if (new_major > old_major ||
-                       (new_major == old_major && new_minor > old_minor)) {
-                       
-                       DEBUG(6,("file_version_is_newer: Replacing [%s] with [%s]\n", old_file, new_file));
-                       return True;
-               }
-               else {
-                       DEBUG(6,("file_version_is_newer: Leaving [%s] unchanged\n", old_file));
-                       return False;
-               }
-
-       } else {
-               /* Compare modification time/dates and choose the newest time/date */
-               if (new_create_time > old_create_time) {
-                       DEBUG(6,("file_version_is_newer: Replacing [%s] with [%s]\n", old_file, new_file));
-                       return True;
-               }
-               else {
-                       DEBUG(6,("file_version_is_newer: Leaving [%s] unchanged\n", old_file));
-                       return False;
-               }
-       }
-
-       error_exit:
-               if(fsp)
-                       close_file(fsp, True);
-               return -1;
-}
-
-/****************************************************************************
-Determine the correct cVersion associated with an architecture and driver
-****************************************************************************/
-static uint32 get_correct_cversion(fstring architecture, fstring driverpath_in,
-                                  struct current_user *user, WERROR *perr)
-{
-       int               cversion;
-       int               access_mode;
-       int               action;
-       NTSTATUS          nt_status;
-       pstring           driverpath;
-       DATA_BLOB         null_pw;
-       files_struct      *fsp = NULL;
-       BOOL              bad_path;
-       SMB_STRUCT_STAT   st;
-       struct tcon_context *conn;
-
-       ZERO_STRUCT(st);
-
-       *perr = WERR_INVALID_PARAM;
-
-       /* If architecture is Windows 95/98/ME, the version is always 0. */
-       if (strcmp(architecture, "WIN40") == 0) {
-               DEBUG(10,("get_correct_cversion: Driver is Win9x, cversion = 0\n"));
-               *perr = WERR_OK;
-               return 0;
-       }
-
-       /*
-        * Connect to the print$ share under the same account as the user connected
-        * to the rpc pipe. Note we must still be root to do this.
-        */
-
-       /* Null password is ok - we are already an authenticated user... */
-       null_pw = data_blob(NULL, 0);
-       become_root();
-       conn = make_connection_with_chdir("print$", null_pw, "A:", user->vuid, &nt_status);
-       unbecome_root();
-
-       if (conn == NULL) {
-               DEBUG(0,("get_correct_cversion: Unable to connect\n"));
-               *perr = ntstatus_to_werror(nt_status);
-               return -1;
-       }
-
-       /* We are temporarily becoming the connection user. */
-       if (!become_user(conn, conn->vuid)) {
-               DEBUG(0,("get_correct_cversion: Can't become user!\n"));
-               *perr = WERR_ACCESS_DENIED;
-               return -1;
-       }
-
-       /* Open the driver file (Portable Executable format) and determine the
-        * deriver the cversion. */
-       slprintf(driverpath, sizeof(driverpath)-1, "%s/%s", architecture, driverpath_in);
-
-       unix_convert(driverpath,conn,NULL,&bad_path,&st);
-
-       fsp = open_file_shared(conn, driverpath, &st,
-                                                  SET_OPEN_MODE(DOS_OPEN_RDONLY),
-                                                  (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
-                                                  0, 0, &access_mode, &action);
-       if (!fsp) {
-               DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = %d\n",
-                               driverpath, errno));
-               *perr = WERR_ACCESS_DENIED;
-               goto error_exit;
-       }
-       else {
-               uint32 major;
-               uint32 minor;
-               int    ret = get_file_version(fsp, driverpath, &major, &minor);
-               if (ret == -1) goto error_exit;
-
-               if (!ret) {
-                       DEBUG(6,("get_correct_cversion: Version info not found [%s]\n", driverpath));
-                       goto error_exit;
-               }
-
-               /*
-                * This is a Microsoft'ism. See references in MSDN to VER_FILEVERSION
-                * for more details. Version in this case is not just the version of the 
-                * file, but the version in the sense of kernal mode (2) vs. user mode
-                * (3) drivers. Other bits of the version fields are the version info. 
-                * JRR 010716
-               */
-               cversion = major & 0x0000ffff;
-               switch (cversion) {
-                       case 2: /* WinNT drivers */
-                       case 3: /* Win2K drivers */
-                               break;
-                       
-                       default:
-                               DEBUG(6,("get_correct_cversion: cversion invalid [%s]  cversion = %d\n", 
-                                       driverpath, cversion));
-                               goto error_exit;
-               }
-
-               DEBUG(10,("get_correct_cversion: Version info found [%s]  major = 0x%x  minor = 0x%x\n",
-                                 driverpath, major, minor));
-       }
-
-    DEBUG(10,("get_correct_cversion: Driver file [%s] cversion = %d\n",
-                       driverpath, cversion));
-
-       close_file(fsp, True);
-       close_cnum(conn, user->vuid);
-       unbecome_user();
-       *perr = WERR_OK;
-       return cversion;
-
-
-  error_exit:
-
-       if(fsp)
-               close_file(fsp, True);
-
-       close_cnum(conn, user->vuid);
-       unbecome_user();
-       return -1;
-}
-
-/****************************************************************************
-****************************************************************************/
-static WERROR clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver,
-                                                                                        struct current_user *user)
-{
-       fstring architecture;
-       fstring new_name;
-       char *p;
-       int i;
-       WERROR err;
-
-       /* clean up the driver name.
-        * we can get .\driver.dll
-        * or worse c:\windows\system\driver.dll !
-        */
-       /* using an intermediate string to not have overlaping memcpy()'s */
-       if ((p = strrchr(driver->driverpath,'\\')) != NULL) {
-               fstrcpy(new_name, p+1);
-               fstrcpy(driver->driverpath, new_name);
-       }
-
-       if ((p = strrchr(driver->datafile,'\\')) != NULL) {
-               fstrcpy(new_name, p+1);
-               fstrcpy(driver->datafile, new_name);
-       }
-
-       if ((p = strrchr(driver->configfile,'\\')) != NULL) {
-               fstrcpy(new_name, p+1);
-               fstrcpy(driver->configfile, new_name);
-       }
-
-       if ((p = strrchr(driver->helpfile,'\\')) != NULL) {
-               fstrcpy(new_name, p+1);
-               fstrcpy(driver->helpfile, new_name);
-       }
-
-       if (driver->dependentfiles) {
-               for (i=0; *driver->dependentfiles[i]; i++) {
-                       if ((p = strrchr(driver->dependentfiles[i],'\\')) != NULL) {
-                               fstrcpy(new_name, p+1);
-                               fstrcpy(driver->dependentfiles[i], new_name);
-                       }
-               }
-       }
-
-       get_short_archi(architecture, driver->environment);
-       
-       /* jfm:7/16/2000 the client always sends the cversion=0.
-        * The server should check which version the driver is by reading
-        * the PE header of driver->driverpath.
-        *
-        * For Windows 95/98 the version is 0 (so the value sent is correct)
-        * For Windows NT (the architecture doesn't matter)
-        *      NT 3.1: cversion=0
-        *      NT 3.5/3.51: cversion=1
-        *      NT 4: cversion=2
-        *      NT2K: cversion=3
-        */
-       if ((driver->cversion = get_correct_cversion( architecture,
-                                                                       driver->driverpath, user, &err)) == -1)
-               return err;
-
-       return WERR_OK;
-}
-       
-/****************************************************************************
-****************************************************************************/
-static WERROR clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver, struct current_user *user)
-{
-       fstring architecture;
-       fstring new_name;
-       char *p;
-       int i;
-       WERROR err;
-
-       /* clean up the driver name.
-        * we can get .\driver.dll
-        * or worse c:\windows\system\driver.dll !
-        */
-       /* using an intermediate string to not have overlaping memcpy()'s */
-       if ((p = strrchr(driver->driverpath,'\\')) != NULL) {
-               fstrcpy(new_name, p+1);
-               fstrcpy(driver->driverpath, new_name);
-       }
-
-       if ((p = strrchr(driver->datafile,'\\')) != NULL) {
-               fstrcpy(new_name, p+1);
-               fstrcpy(driver->datafile, new_name);
-       }
-
-       if ((p = strrchr(driver->configfile,'\\')) != NULL) {
-               fstrcpy(new_name, p+1);
-               fstrcpy(driver->configfile, new_name);
-       }
-
-       if ((p = strrchr(driver->helpfile,'\\')) != NULL) {
-               fstrcpy(new_name, p+1);
-               fstrcpy(driver->helpfile, new_name);
-       }
-
-       if (driver->dependentfiles) {
-               for (i=0; *driver->dependentfiles[i]; i++) {
-                       if ((p = strrchr(driver->dependentfiles[i],'\\')) != NULL) {
-                               fstrcpy(new_name, p+1);
-                               fstrcpy(driver->dependentfiles[i], new_name);
-                       }
-               }
-       }
-
-       get_short_archi(architecture, driver->environment);
-
-       /* jfm:7/16/2000 the client always sends the cversion=0.
-        * The server should check which version the driver is by reading
-        * the PE header of driver->driverpath.
-        *
-        * For Windows 95/98 the version is 0 (so the value sent is correct)
-        * For Windows NT (the architecture doesn't matter)
-        *      NT 3.1: cversion=0
-        *      NT 3.5/3.51: cversion=1
-        *      NT 4: cversion=2
-        *      NT2K: cversion=3
-        */
-       if ((driver->version = get_correct_cversion(architecture, driver->driverpath, user, &err)) == -1)
-               return err;
-
-       return WERR_OK;
-}
-
-/****************************************************************************
-****************************************************************************/
-WERROR clean_up_driver_struct(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
-                                                         uint32 level, struct current_user *user)
-{
-       switch (level) {
-               case 3:
-               {
-                       NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
-                       driver=driver_abstract.info_3;
-                       return clean_up_driver_struct_level_3(driver, user);
-               }
-               case 6:
-               {
-                       NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver;
-                       driver=driver_abstract.info_6;
-                       return clean_up_driver_struct_level_6(driver, user);
-               }
-               default:
-                       return WERR_INVALID_PARAM;
-       }
-}
-
-/****************************************************************************
- This function sucks and should be replaced. JRA.
-****************************************************************************/
-
-static void convert_level_6_to_level3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *dst, NT_PRINTER_DRIVER_INFO_LEVEL_6 *src)
-{
-    dst->cversion  = src->version;
-
-    fstrcpy( dst->name, src->name);
-    fstrcpy( dst->environment, src->environment);
-    fstrcpy( dst->driverpath, src->driverpath);
-    fstrcpy( dst->datafile, src->datafile);
-    fstrcpy( dst->configfile, src->configfile);
-    fstrcpy( dst->helpfile, src->helpfile);
-    fstrcpy( dst->monitorname, src->monitorname);
-    fstrcpy( dst->defaultdatatype, src->defaultdatatype);
-    dst->dependentfiles = src->dependentfiles;
-}
-
-#if 0 /* Debugging function */
-
-static char* ffmt(unsigned char *c){
-       int i;
-       static char ffmt_str[17];
-
-       for (i=0; i<16; i++) {
-               if ((c[i] < ' ') || (c[i] > '~'))
-                       ffmt_str[i]='.';
-               else
-                       ffmt_str[i]=c[i];
-       }
-    ffmt_str[16]='\0';
-       return ffmt_str;
-}
-
-#endif
-
-/****************************************************************************
-****************************************************************************/
-BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, uint32 level, 
-                                 struct current_user *user, WERROR *perr)
-{
-       NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
-       NT_PRINTER_DRIVER_INFO_LEVEL_3 converted_driver;
-       fstring architecture;
-       pstring new_dir;
-       pstring old_name;
-       pstring new_name;
-       DATA_BLOB null_pw;
-       struct tcon_context *conn;
-       NTSTATUS nt_status;
-       pstring inbuf;
-       pstring outbuf;
-       int ver = 0;
-       int i;
-
-       memset(inbuf, '\0', sizeof(inbuf));
-       memset(outbuf, '\0', sizeof(outbuf));
-       *perr = WERR_OK;
-
-       if (level==3)
-               driver=driver_abstract.info_3;
-       else if (level==6) {
-               convert_level_6_to_level3(&converted_driver, driver_abstract.info_6);
-               driver = &converted_driver;
-       } else {
-               DEBUG(0,("move_driver_to_download_area: Unknown info level (%u)\n", (unsigned int)level ));
-               return False;
-       }
-
-       get_short_archi(architecture, driver->environment);
-
-       /*
-        * Connect to the print$ share under the same account as the user connected to the rpc pipe.
-        * Note we must be root to do this.
-        */
-
-       become_root();
-       null_pw = data_blob(NULL, 0);
-       conn = make_connection_with_chdir("print$", null_pw, "A:", user->vuid, &nt_status);
-       unbecome_root();
-
-       if (conn == NULL) {
-               DEBUG(0,("move_driver_to_download_area: Unable to connect\n"));
-               *perr = ntstatus_to_werror(nt_status);
-               return False;
-       }
-
-       /*
-        * Save who we are - we are temporarily becoming the connection user.
-        */
-
-       if (!become_user(conn, conn->vuid)) {
-               DEBUG(0,("move_driver_to_download_area: Can't become user!\n"));
-               return False;
-       }
-
-       /*
-        * make the directories version and version\driver_name
-        * under the architecture directory.
-        */
-       DEBUG(5,("Creating first directory\n"));
-       slprintf(new_dir, sizeof(new_dir)-1, "%s/%d", architecture, driver->cversion);
-       mkdir_internal(conn, new_dir);
-
-       /* For each driver file, archi\filexxx.yyy, if there is a duplicate file
-        * listed for this driver which has already been moved, skip it (note:
-        * drivers may list the same file name several times. Then check if the
-        * file already exists in archi\cversion\, if so, check that the version
-        * info (or time stamps if version info is unavailable) is newer (or the
-        * date is later). If it is, move it to archi\cversion\filexxx.yyy.
-        * Otherwise, delete the file.
-        *
-        * If a file is not moved to archi\cversion\ because of an error, all the
-        * rest of the 'unmoved' driver files are removed from archi\. If one or
-        * more of the driver's files was already moved to archi\cversion\, it
-        * potentially leaves the driver in a partially updated state. Version
-        * trauma will most likely occur if an client attempts to use any printer
-        * bound to the driver. Perhaps a rewrite to make sure the moves can be
-        * done is appropriate... later JRR
-        */
-
-       DEBUG(5,("Moving files now !\n"));
-
-       if (driver->driverpath && strlen(driver->driverpath)) {
-               slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->driverpath);      
-               slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->driverpath);   
-               if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
-                       NTSTATUS status;
-                       status = rename_internals(conn, new_name, old_name, True);
-                       if (!NT_STATUS_IS_OK(status)) {
-                               DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
-                                               new_name, old_name));
-                               *perr = ntstatus_to_werror(status);
-                               unlink_internals(conn, 0, new_name);
-                               ver = -1;
-                       }
-               }
-               else
-                       unlink_internals(conn, 0, new_name);
-       }
-
-       if (driver->datafile && strlen(driver->datafile)) {
-               if (!strequal(driver->datafile, driver->driverpath)) {
-                       slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->datafile);        
-                       slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->datafile);     
-                       if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
-                               NTSTATUS status;
-                               status = rename_internals(conn, new_name, old_name, True);
-                               if (!NT_STATUS_IS_OK(status)) {
-                                       DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
-                                                       new_name, old_name));
-                                       *perr = ntstatus_to_werror(status);
-                                       unlink_internals(conn, 0, new_name);
-                                       ver = -1;
-                               }
-                       }
-                       else
-                               unlink_internals(conn, 0, new_name);
-               }
-       }
-
-       if (driver->configfile && strlen(driver->configfile)) {
-               if (!strequal(driver->configfile, driver->driverpath) &&
-                       !strequal(driver->configfile, driver->datafile)) {
-                       slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->configfile);      
-                       slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->configfile);   
-                       if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
-                               NTSTATUS status;
-                               status = rename_internals(conn, new_name, old_name, True);
-                               if (!NT_STATUS_IS_OK(status)) {
-                                       DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
-                                                       new_name, old_name));
-                                       *perr = ntstatus_to_werror(status);
-                                       unlink_internals(conn, 0, new_name);
-                                       ver = -1;
-                               }
-                       }
-                       else
-                               unlink_internals(conn, 0, new_name);
-               }
-       }
-
-       if (driver->helpfile && strlen(driver->helpfile)) {
-               if (!strequal(driver->helpfile, driver->driverpath) &&
-                       !strequal(driver->helpfile, driver->datafile) &&
-                       !strequal(driver->helpfile, driver->configfile)) {
-                       slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->helpfile);        
-                       slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->helpfile);     
-                       if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
-                               NTSTATUS status;
-                               status = rename_internals(conn, new_name, old_name, True);
-                               if (!NT_STATUS_IS_OK(status)) {
-                                       DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
-                                                       new_name, old_name));
-                                       *perr = ntstatus_to_werror(status);
-                                       unlink_internals(conn, 0, new_name);
-                                       ver = -1;
-                               }
-                       }
-                       else
-                               unlink_internals(conn, 0, new_name);
-               }
-       }
-
-       if (driver->dependentfiles) {
-               for (i=0; *driver->dependentfiles[i]; i++) {
-                       if (!strequal(driver->dependentfiles[i], driver->driverpath) &&
-                               !strequal(driver->dependentfiles[i], driver->datafile) &&
-                               !strequal(driver->dependentfiles[i], driver->configfile) &&
-                               !strequal(driver->dependentfiles[i], driver->helpfile)) {
-                               int j;
-                               for (j=0; j < i; j++) {
-                                       if (strequal(driver->dependentfiles[i], driver->dependentfiles[j])) {
-                                               goto NextDriver;
-                                       }
-                               }
-
-                               slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->dependentfiles[i]);       
-                               slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->dependentfiles[i]);    
-                               if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
-                                       NTSTATUS status;
-                                       status = rename_internals(conn, new_name, old_name, True);
-                                       if (!NT_STATUS_IS_OK(status)) {
-                                               DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
-                                                               new_name, old_name));
-                                               *perr = ntstatus_to_werror(status);
-                                               unlink_internals(conn, 0, new_name);
-                                               ver = -1;
-                                       }
-                               }
-                               else
-                                       unlink_internals(conn, 0, new_name);
-                       }
-               NextDriver: ;
-               }
-       }
-
-       close_cnum(conn, user->vuid);
-       unbecome_user();
-
-       return ver == -1 ? False : True;
-}
-
-/****************************************************************************
-****************************************************************************/
-static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
-{
-       int len, buflen;
-       fstring architecture;
-       pstring directory;
-       fstring temp_name;
-       pstring key;
-       char *buf;
-       int i, ret;
-       TDB_DATA kbuf, dbuf;
-
-       get_short_archi(architecture, driver->environment);
-
-       /* The names are relative. We store them in the form: \print$\arch\version\driver.xxx
-        * \\server is added in the rpc server layer.
-        * It does make sense to NOT store the server's name in the printer TDB.
-        */
-
-       slprintf(directory, sizeof(directory)-1, "\\print$\\%s\\%d\\", architecture, driver->cversion);
-
-       /* .inf files do not always list a file for each of the four standard files. 
-        * Don't prepend a path to a null filename, or client claims:
-        *   "The server on which the printer resides does not have a suitable 
-        *   <printer driver name> printer driver installed. Click OK if you 
-        *   wish to install the driver on your local machine."
-        */
-       if (strlen(driver->driverpath)) {
-               fstrcpy(temp_name, driver->driverpath);
-               slprintf(driver->driverpath, sizeof(driver->driverpath)-1, "%s%s", directory, temp_name);
-       }
-
-       if (strlen(driver->datafile)) {
-               fstrcpy(temp_name, driver->datafile);
-               slprintf(driver->datafile, sizeof(driver->datafile)-1, "%s%s", directory, temp_name);
-       }
-
-       if (strlen(driver->configfile)) {
-               fstrcpy(temp_name, driver->configfile);
-               slprintf(driver->configfile, sizeof(driver->configfile)-1, "%s%s", directory, temp_name);
-       }
-
-       if (strlen(driver->helpfile)) {
-               fstrcpy(temp_name, driver->helpfile);
-               slprintf(driver->helpfile, sizeof(driver->helpfile)-1, "%s%s", directory, temp_name);
-       }
-
-       if (driver->dependentfiles) {
-               for (i=0; *driver->dependentfiles[i]; i++) {
-                       fstrcpy(temp_name, driver->dependentfiles[i]);
-                       slprintf(driver->dependentfiles[i], sizeof(driver->dependentfiles[i])-1, "%s%s", directory, temp_name);
-               }
-       }
-
-       slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, architecture, driver->cversion, driver->name);
-
-       DEBUG(5,("add_a_printer_driver_3: Adding driver with key %s\n", key ));
-
-       buf = NULL;
-       len = buflen = 0;
-
- again:
-       len = 0;
-       len += tdb_pack(buf+len, buflen-len, "dffffffff",
-                       driver->cversion,
-                       driver->name,
-                       driver->environment,
-                       driver->driverpath,
-                       driver->datafile,
-                       driver->configfile,
-                       driver->helpfile,
-                       driver->monitorname,
-                       driver->defaultdatatype);
-
-       if (driver->dependentfiles) {
-               for (i=0; *driver->dependentfiles[i]; i++) {
-                       len += tdb_pack(buf+len, buflen-len, "f",
-                                       driver->dependentfiles[i]);
-               }
-       }
-
-       if (len != buflen) {
-               char *tb;
-
-               tb = (char *)Realloc(buf, len);
-               if (!tb) {
-                       DEBUG(0,("add_a_printer_driver_3: failed to enlarge buffer\n!"));
-                       ret = -1;
-                       goto done;
-               }
-               else buf = tb;
-               buflen = len;
-               goto again;
-       }
-
-
-       kbuf.dptr = key;
-       kbuf.dsize = strlen(key)+1;
-       dbuf.dptr = buf;
-       dbuf.dsize = len;
-       
-       ret = tdb_store(tdb_drivers, kbuf, dbuf, TDB_REPLACE);
-
-done:
-       if (ret)
-               DEBUG(0,("add_a_printer_driver_3: Adding driver with key %s failed.\n", key ));
-
-       SAFE_FREE(buf);
-       return ret;
-}
-
-/****************************************************************************
-****************************************************************************/
-static uint32 add_a_printer_driver_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver)
-{
-       NT_PRINTER_DRIVER_INFO_LEVEL_3 info3;
-
-       ZERO_STRUCT(info3);
-       info3.cversion = driver->version;
-       fstrcpy(info3.name,driver->name);
-       fstrcpy(info3.environment,driver->environment);
-       fstrcpy(info3.driverpath,driver->driverpath);
-       fstrcpy(info3.datafile,driver->datafile);
-       fstrcpy(info3.configfile,driver->configfile);
-       fstrcpy(info3.helpfile,driver->helpfile);
-       fstrcpy(info3.monitorname,driver->monitorname);
-       fstrcpy(info3.defaultdatatype,driver->defaultdatatype);
-       info3.dependentfiles = driver->dependentfiles;
-
-       return add_a_printer_driver_3(&info3);
-}
-
-
-/****************************************************************************
-****************************************************************************/
-static WERROR get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, const char *driver, const char *arch)
-{
-       NT_PRINTER_DRIVER_INFO_LEVEL_3 info;
-
-       ZERO_STRUCT(info);
-
-       fstrcpy(info.name, driver);
-       fstrcpy(info.defaultdatatype, "RAW");
-       
-       fstrcpy(info.driverpath, "");
-       fstrcpy(info.datafile, "");
-       fstrcpy(info.configfile, "");
-       fstrcpy(info.helpfile, "");
-
-       if ((info.dependentfiles=(fstring *)malloc(2*sizeof(fstring))) == NULL)
-               return WERR_NOMEM;
-
-       memset(info.dependentfiles, '\0', 2*sizeof(fstring));
-       fstrcpy(info.dependentfiles[0], "");
-
-       *info_ptr = memdup(&info, sizeof(info));
-       
-       return WERR_OK;
-}
-
-/****************************************************************************
-****************************************************************************/
-static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring drivername, const char *arch, uint32 version)
-{
-       NT_PRINTER_DRIVER_INFO_LEVEL_3 driver;
-       TDB_DATA kbuf, dbuf;
-       fstring architecture;
-       int len = 0;
-       int i;
-       pstring key;
-
-       ZERO_STRUCT(driver);
-
-       get_short_archi(architecture, arch);
-
-       DEBUG(8,("get_a_printer_driver_3: [%s%s/%d/%s]\n", DRIVERS_PREFIX, architecture, version, drivername));
-
-       slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, architecture, version, drivername);
-
-       kbuf.dptr = key;
-       kbuf.dsize = strlen(key)+1;
-       
-       dbuf = tdb_fetch(tdb_drivers, kbuf);
-       if (!dbuf.dptr) 
-               return WERR_UNKNOWN_PRINTER_DRIVER;
-
-       len += tdb_unpack(dbuf.dptr, dbuf.dsize, "dffffffff",
-                         &driver.cversion,
-                         driver.name,
-                         driver.environment,
-                         driver.driverpath,
-                         driver.datafile,
-                         driver.configfile,
-                         driver.helpfile,
-                         driver.monitorname,
-                         driver.defaultdatatype);
-
-       i=0;
-       while (len < dbuf.dsize) {
-               fstring *tddfs;
-
-               tddfs = (fstring *)Realloc(driver.dependentfiles,
-                                                        sizeof(fstring)*(i+2));
-               if (tddfs == NULL) {
-                       DEBUG(0,("get_a_printer_driver_3: failed to enlarge buffer!\n"));
-                       break;
-               }
-               else driver.dependentfiles = tddfs;
-
-               len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "f",
-                                 &driver.dependentfiles[i]);
-               i++;
-       }
-       
-       if (driver.dependentfiles != NULL)
-               fstrcpy(driver.dependentfiles[i], "");
-
-       SAFE_FREE(dbuf.dptr);
-
-       if (len != dbuf.dsize) {
-               SAFE_FREE(driver.dependentfiles);
-
-               return get_a_printer_driver_3_default(info_ptr, drivername, arch);
-       }
-
-       *info_ptr = (NT_PRINTER_DRIVER_INFO_LEVEL_3 *)memdup(&driver, sizeof(driver));
-
-       return WERR_OK;
-}
-
-/****************************************************************************
- Debugging function, dump at level 6 the struct in the logs.
-****************************************************************************/
-
-static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
-{
-       uint32 result;
-       NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
-       int i;
-       
-       DEBUG(20,("Dumping printer driver at level [%d]\n", level));
-       
-       switch (level)
-       {
-               case 3:
-               {
-                       if (driver.info_3 == NULL)
-                               result=5;
-                       else {
-                               info3=driver.info_3;
-                       
-                               DEBUGADD(20,("version:[%d]\n",         info3->cversion));
-                               DEBUGADD(20,("name:[%s]\n",            info3->name));
-                               DEBUGADD(20,("environment:[%s]\n",     info3->environment));
-                               DEBUGADD(20,("driverpath:[%s]\n",      info3->driverpath));
-                               DEBUGADD(20,("datafile:[%s]\n",        info3->datafile));
-                               DEBUGADD(20,("configfile:[%s]\n",      info3->configfile));
-                               DEBUGADD(20,("helpfile:[%s]\n",        info3->helpfile));
-                               DEBUGADD(20,("monitorname:[%s]\n",     info3->monitorname));
-                               DEBUGADD(20,("defaultdatatype:[%s]\n", info3->defaultdatatype));
-                               
-                               for (i=0; info3->dependentfiles &&
-                                         *info3->dependentfiles[i]; i++) {
-                                       DEBUGADD(20,("dependentfile:[%s]\n",
-                                                     info3->dependentfiles[i]));
-                               }
-                               result=0;
-                       }
-                       break;
-               }
-               default:
-                       DEBUGADD(20,("dump_a_printer_driver: Level %u not implemented\n", (unsigned int)level));
-                       result=1;
-                       break;
-       }
-       
-       return result;
-}
-
-/****************************************************************************
-****************************************************************************/
-int pack_devicemode(NT_DEVICEMODE *nt_devmode, char *buf, int buflen)
-{
-       int len = 0;
-
-       len += tdb_pack(buf+len, buflen-len, "p", nt_devmode);
-
-       if (!nt_devmode)
-               return len;
-
-       len += tdb_pack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
-                       nt_devmode->devicename,
-                       nt_devmode->formname,
-
-                       nt_devmode->specversion,
-                       nt_devmode->driverversion,
-                       nt_devmode->size,
-                       nt_devmode->driverextra,
-                       nt_devmode->orientation,
-                       nt_devmode->papersize,
-                       nt_devmode->paperlength,
-                       nt_devmode->paperwidth,
-                       nt_devmode->scale,
-                       nt_devmode->copies,
-                       nt_devmode->defaultsource,
-                       nt_devmode->printquality,
-                       nt_devmode->color,
-                       nt_devmode->duplex,
-                       nt_devmode->yresolution,
-                       nt_devmode->ttoption,
-                       nt_devmode->collate,
-                       nt_devmode->logpixels,
-                       
-                       nt_devmode->fields,
-                       nt_devmode->bitsperpel,
-                       nt_devmode->pelswidth,
-                       nt_devmode->pelsheight,
-                       nt_devmode->displayflags,
-                       nt_devmode->displayfrequency,
-                       nt_devmode->icmmethod,
-                       nt_devmode->icmintent,
-                       nt_devmode->mediatype,
-                       nt_devmode->dithertype,
-                       nt_devmode->reserved1,
-                       nt_devmode->reserved2,
-                       nt_devmode->panningwidth,
-                       nt_devmode->panningheight,
-                       nt_devmode->private);
-
-       
-       if (nt_devmode->private) {
-               len += tdb_pack(buf+len, buflen-len, "B",
-                               nt_devmode->driverextra,
-                               nt_devmode->private);
-       }
-
-       DEBUG(8,("Packed devicemode [%s]\n", nt_devmode->formname));
-
-       return len;
-}
-
-/****************************************************************************
- Pack all values in all printer keys
- ***************************************************************************/
-static int pack_values(NT_PRINTER_DATA *data, char *buf, int buflen)
-{
-       int             len = 0;
-       int             i, j;
-       REGISTRY_VALUE  *val;
-       REGVAL_CTR      *val_ctr;
-       pstring         path;
-       int             num_values;
-
-       if ( !data )
-               return 0;
-
-       /* loop over all keys */
-               
-       for ( i=0; i<data->num_keys; i++ ) {    
-               val_ctr = &data->keys[i].values;
-               num_values = regval_ctr_numvals( val_ctr );
-               
-               /* loop over all values */
-               
-               for ( j=0; j<num_values; j++ ) {
-                       /* pathname should be stored as <key>\<value> */
-                       
-                       val = regval_ctr_specific_value( val_ctr, j );
-                       pstrcpy( path, data->keys[i].name );
-                       pstrcat( path, "\\" );
-                       pstrcat( path, regval_name(val) );
-                       
-                       len += tdb_pack(buf+len, buflen-len, "pPdB",
-                                       val,
-                                       path,
-                                       regval_type(val),
-                                       regval_size(val),
-                                       regval_data_p(val) );
-               }
-       
-       }
-
-       /* terminator */
-       
-       len += tdb_pack(buf+len, buflen-len, "p", NULL);
-
-       return len;
-}
-
-
-/****************************************************************************
- Delete a printer - this just deletes the printer info file, any open
- handles are not affected.
-****************************************************************************/
-
-uint32 del_a_printer(char *sharename)
-{
-       pstring key;
-       TDB_DATA kbuf;
-
-       slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, sharename);
-
-       kbuf.dptr=key;
-       kbuf.dsize=strlen(key)+1;
-
-       tdb_delete(tdb_printers, kbuf);
-       return 0;
-}
-
-/* FIXME!!!  Reorder so this forward declaration is not necessary --jerry */
-static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **, const char* sharename);
-static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **);
-/****************************************************************************
-****************************************************************************/
-static WERROR update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
-{
-       pstring key;
-       char *buf;
-       int buflen, len;
-       WERROR ret;
-       TDB_DATA kbuf, dbuf;
-       
-       /*
-        * in addprinter: no servername and the printer is the name
-        * in setprinter: servername is \\server
-        *                and printer is \\server\\printer
-        *
-        * Samba manages only local printers.
-        * we currently don't support things like path=\\other_server\printer
-        */
-
-       if (info->servername[0]!='\0') {
-               trim_string(info->printername, info->servername, NULL);
-               trim_string(info->printername, "\\", NULL);
-               info->servername[0]='\0';
-       }
-
-       /*
-        * JFM: one day I'll forget.
-        * below that's info->portname because that's the SAMBA sharename
-        * and I made NT 'thinks' it's the portname
-        * the info->sharename is the thing you can name when you add a printer
-        * that's the short-name when you create shared printer for 95/98
-        * So I've made a limitation in SAMBA: you can only have 1 printer model
-        * behind a SAMBA share.
-        */
-
-       buf = NULL;
-       buflen = 0;
-
- again:        
-       len = 0;
-       len += tdb_pack(buf+len, buflen-len, "dddddddddddfffffPfffff",
-                       info->attributes,
-                       info->priority,
-                       info->default_priority,
-                       info->starttime,
-                       info->untiltime,
-                       info->status,
-                       info->cjobs,
-                       info->averageppm,
-                       info->changeid,
-                       info->c_setprinter,
-                       info->setuptime,
-                       info->servername,
-                       info->printername,
-                       info->sharename,
-                       info->portname,
-                       info->drivername,
-                       info->comment,
-                       info->location,
-                       info->sepfile,
-                       info->printprocessor,
-                       info->datatype,
-                       info->parameters);
-
-       len += pack_devicemode(info->devmode, buf+len, buflen-len);
-       
-       len += pack_values( &info->data, buf+len, buflen-len );
-
-       if (buflen != len) {
-               char *tb;
-
-               tb = (char *)Realloc(buf, len);
-               if (!tb) {
-                       DEBUG(0,("update_a_printer_2: failed to enlarge buffer!\n"));
-                       ret = WERR_NOMEM;
-                       goto done;
-               }
-               else buf = tb;
-               buflen = len;
-               goto again;
-       }
-       
-
-       slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, info->sharename);
-
-       kbuf.dptr = key;
-       kbuf.dsize = strlen(key)+1;
-       dbuf.dptr = buf;
-       dbuf.dsize = len;
-
-       ret = (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) == 0? WERR_OK : WERR_NOMEM);
-
-done:
-       if (!W_ERROR_IS_OK(ret))
-               DEBUG(8, ("error updating printer to tdb on disk\n"));
-
-       SAFE_FREE(buf);
-
-       DEBUG(8,("packed printer [%s] with driver [%s] portname=[%s] len=%d\n",
-                info->sharename, info->drivername, info->portname, len));
-
-       return ret;
-}
-
-
-/****************************************************************************
- Malloc and return an NT devicemode.
-****************************************************************************/
-
-NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename)
-{
-
-       char adevice[32];
-       NT_DEVICEMODE *nt_devmode = (NT_DEVICEMODE *)malloc(sizeof(NT_DEVICEMODE));
-
-       if (nt_devmode == NULL) {
-               DEBUG(0,("construct_nt_devicemode: malloc fail.\n"));
-               return NULL;
-       }
-
-       ZERO_STRUCTP(nt_devmode);
-
-       safe_strcpy(adevice, default_devicename, sizeof(adevice));
-       fstrcpy(nt_devmode->devicename, adevice);       
-       
-       fstrcpy(nt_devmode->formname, "Letter");
-
-       nt_devmode->specversion      = 0x0401;
-       nt_devmode->driverversion    = 0x0400;
-       nt_devmode->size             = 0x00DC;
-       nt_devmode->driverextra      = 0x0000;
-       nt_devmode->fields           = FORMNAME | TTOPTION | PRINTQUALITY |
-                                      DEFAULTSOURCE | COPIES | SCALE |
-                                      PAPERSIZE | ORIENTATION;
-       nt_devmode->orientation      = 1;
-       nt_devmode->papersize        = PAPER_LETTER;
-       nt_devmode->paperlength      = 0;
-       nt_devmode->paperwidth       = 0;
-       nt_devmode->scale            = 0x64;
-       nt_devmode->copies           = 1;
-       nt_devmode->defaultsource    = BIN_FORMSOURCE;
-       nt_devmode->printquality     = RES_HIGH;           /* 0x0258 */
-       nt_devmode->color            = COLOR_MONOCHROME;
-       nt_devmode->duplex           = DUP_SIMPLEX;
-       nt_devmode->yresolution      = 0;
-       nt_devmode->ttoption         = TT_SUBDEV;
-       nt_devmode->collate          = COLLATE_FALSE;
-       nt_devmode->icmmethod        = 0;
-       nt_devmode->icmintent        = 0;
-       nt_devmode->mediatype        = 0;
-       nt_devmode->dithertype       = 0;
-
-       /* non utilisés par un driver d'imprimante */
-       nt_devmode->logpixels        = 0;
-       nt_devmode->bitsperpel       = 0;
-       nt_devmode->pelswidth        = 0;
-       nt_devmode->pelsheight       = 0;
-       nt_devmode->displayflags     = 0;
-       nt_devmode->displayfrequency = 0;
-       nt_devmode->reserved1        = 0;
-       nt_devmode->reserved2        = 0;
-       nt_devmode->panningwidth     = 0;
-       nt_devmode->panningheight    = 0;
-       
-       nt_devmode->private = NULL;
-       return nt_devmode;
-}
-
-/****************************************************************************
- Deepcopy an NT devicemode.
-****************************************************************************/
-
-NT_DEVICEMODE *dup_nt_devicemode(NT_DEVICEMODE *nt_devicemode)
-{
-       NT_DEVICEMODE *new_nt_devicemode = NULL;
-
-       if ( !nt_devicemode )
-               return NULL;
-
-       if ((new_nt_devicemode = (NT_DEVICEMODE *)memdup(nt_devicemode, sizeof(NT_DEVICEMODE))) == NULL) {
-               DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
-               return NULL;
-       }
-
-       new_nt_devicemode->private = NULL;
-       if (nt_devicemode->private != NULL) {
-               if ((new_nt_devicemode->private = memdup(nt_devicemode->private, nt_devicemode->driverextra)) == NULL) {
-                       SAFE_FREE(new_nt_devicemode);
-                       DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
-                       return NULL;
-        }
-       }
-
-       return new_nt_devicemode;
-}
-
-/****************************************************************************
- Clean up and deallocate a (maybe partially) allocated NT_DEVICEMODE.
-****************************************************************************/
-
-void free_nt_devicemode(NT_DEVICEMODE **devmode_ptr)
-{
-       NT_DEVICEMODE *nt_devmode = *devmode_ptr;
-
-       if(nt_devmode == NULL)
-               return;
-
-       DEBUG(106,("free_nt_devicemode: deleting DEVMODE\n"));
-
-       SAFE_FREE(nt_devmode->private);
-       SAFE_FREE(*devmode_ptr);
-}
-
-/****************************************************************************
- Clean up and deallocate a (maybe partially) allocated NT_PRINTER_INFO_LEVEL_2.
-****************************************************************************/
-static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr)
-{
-       NT_PRINTER_INFO_LEVEL_2 *info = *info_ptr;
-       NT_PRINTER_DATA         *data;
-       int                     i;
-
-       if ( !info )
-               return;
-
-       DEBUG(106,("free_nt_printer_info_level_2: deleting info\n"));
-
-       free_nt_devicemode(&info->devmode);
-
-       /* clean up all registry keys */
-       
-       data = &info->data;
-       for ( i=0; i<data->num_keys; i++ ) {
-               SAFE_FREE( data->keys[i].name );
-               regval_ctr_destroy( &data->keys[i].values );
-       }
-       SAFE_FREE( data->keys );
-
-       /* finally the top level structure */
-       
-       SAFE_FREE( *info_ptr );
-}
-
-
-/****************************************************************************
-****************************************************************************/
-int unpack_devicemode(NT_DEVICEMODE **nt_devmode, char *buf, int buflen)
-{
-       int len = 0;
-       int extra_len = 0;
-       NT_DEVICEMODE devmode;
-
-       ZERO_STRUCT(devmode);
-
-       len += tdb_unpack(buf+len, buflen-len, "p", nt_devmode);
-
-       if (!*nt_devmode) return len;
-
-       len += tdb_unpack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
-                         devmode.devicename,
-                         devmode.formname,
-
-                         &devmode.specversion,
-                         &devmode.driverversion,
-                         &devmode.size,
-                         &devmode.driverextra,
-                         &devmode.orientation,
-                         &devmode.papersize,
-                         &devmode.paperlength,
-                         &devmode.paperwidth,
-                         &devmode.scale,
-                         &devmode.copies,
-                         &devmode.defaultsource,
-                         &devmode.printquality,
-                         &devmode.color,
-                         &devmode.duplex,
-                         &devmode.yresolution,
-                         &devmode.ttoption,
-                         &devmode.collate,
-                         &devmode.logpixels,
-                       
-                         &devmode.fields,
-                         &devmode.bitsperpel,
-                         &devmode.pelswidth,
-                         &devmode.pelsheight,
-                         &devmode.displayflags,
-                         &devmode.displayfrequency,
-                         &devmode.icmmethod,
-                         &devmode.icmintent,
-                         &devmode.mediatype,
-                         &devmode.dithertype,
-                         &devmode.reserved1,
-                         &devmode.reserved2,
-                         &devmode.panningwidth,
-                         &devmode.panningheight,
-                         &devmode.private);
-       
-       if (devmode.private) {
-               /* the len in tdb_unpack is an int value and
-                * devmode.driverextra is only a short
-                */
-               len += tdb_unpack(buf+len, buflen-len, "B", &extra_len, &devmode.private);
-               devmode.driverextra=(uint16)extra_len;
-               
-               /* check to catch an invalid TDB entry so we don't segfault */
-               if (devmode.driverextra == 0) {
-                       devmode.private = NULL;
-               }
-       }
-
-       *nt_devmode = (NT_DEVICEMODE *)memdup(&devmode, sizeof(devmode));
-
-       DEBUG(8,("Unpacked devicemode [%s](%s)\n", devmode.devicename, devmode.formname));
-       if (devmode.private)
-               DEBUG(8,("with a private section of %d bytes\n", devmode.driverextra));
-
-       return len;
-}
-
-/****************************************************************************
- Allocate and initialize a new slot.
-***************************************************************************/
-static int add_new_printer_key( NT_PRINTER_DATA *data, const char *name )
-{
-       NT_PRINTER_KEY  *d;
-       int             key_index;
-       
-       if ( !data || !name )
-               return -1;
-       
-       /* allocate another slot in the NT_PRINTER_KEY array */
-       
-       d = Realloc( data->keys, sizeof(NT_PRINTER_KEY)*(data->num_keys+1) );
-       if ( d )
-               data->keys = d;
-       
-       key_index = data->num_keys;
-       
-       /* initialze new key */
-       
-       data->num_keys++;
-       data->keys[key_index].name = strdup( name );
-       
-       ZERO_STRUCTP( &data->keys[key_index].values );
-       
-       regval_ctr_init( &data->keys[key_index].values );
-       
-       DEBUG(10,("add_new_printer_key: Inserted new data key [%s]\n", name ));
-       
-       return key_index;
-}
-
-/****************************************************************************
- search for a registry key name in the existing printer data
- ***************************************************************************/
-int lookup_printerkey( NT_PRINTER_DATA *data, const char *name )
-{
-       int             key_index = -1;
-       int             i;
-       
-       if ( !data || !name )
-               return -1;
-
-       DEBUG(12,("lookup_printerkey: Looking for [%s]\n", name));
-
-       /* loop over all existing keys */
-       
-       for ( i=0; i<data->num_keys; i++ ) {
-               if ( strequal(data->keys[i].name, name) ) {
-                       DEBUG(12,("lookup_printerkey: Found [%s]!\n", name));
-                       key_index = i;
-                       break;
-               
-               }
-       }
-       
-       return key_index;
-}
-
-/****************************************************************************
- ***************************************************************************/
-
-uint32 get_printer_subkeys( NT_PRINTER_DATA *data, const char* key, fstring **subkeys )
-{
-       int     i, j;
-       int     key_len;
-       int     num_subkeys = 0;
-       char    *p;
-       fstring *ptr, *subkeys_ptr = NULL;
-       fstring subkeyname;
-       
-       if ( !data )
-               return 0;
-               
-       for ( i=0; i<data->num_keys; i++ ) {
-               if ( StrnCaseCmp(data->keys[i].name, key, strlen(key)) == 0 ) {
-                       /* match sure it is a subkey and not the key itself */
-                       
-                       key_len = strlen( key );
-                       if ( strlen(data->keys[i].name) == key_len )
-                               continue;
-                       
-                       /* get subkey path */
-
-                       p = data->keys[i].name + key_len;
-                       if ( *p == '\\' )
-                               p++;
-                       fstrcpy( subkeyname, p );
-                       if ( (p = strchr( subkeyname, '\\' )) )
-                               *p = '\0';
-                       
-                       /* don't add a key more than once */
-                       
-                       for ( j=0; j<num_subkeys; j++ ) {
-                               if ( strequal( subkeys_ptr[j], subkeyname ) )
-                                       break;
-                       }
-                       
-                       if ( j != num_subkeys )
-                               continue;
-
-                       /* found a match, so allocate space and copy the name */
-                       
-                       if ( !(ptr = Realloc( subkeys_ptr, (num_subkeys+2)*sizeof(fstring))) ) {
-                               DEBUG(0,("get_printer_subkeys: Realloc failed for [%d] entries!\n", 
-                                       num_subkeys+1));
-                               SAFE_FREE( subkeys );
-                               return 0;
-                       }
-                       
-                       subkeys_ptr = ptr;
-                       fstrcpy( subkeys_ptr[num_subkeys], subkeyname );
-                       num_subkeys++;
-               }
-               
-       }
-       
-       /* tag of the end */
-       
-       if (num_subkeys)
-               fstrcpy(subkeys_ptr[num_subkeys], "" );
-       
-       *subkeys = subkeys_ptr;
-
-       return num_subkeys;
-}
-
-static void map_sz_into_ctr(REGVAL_CTR *ctr, const char *val_name, 
-                           const char *sz)
-{
-       smb_ucs2_t conv_str[1024];
-       size_t str_size;
-
-       regval_ctr_delvalue(ctr, val_name);
-       str_size = push_ucs2(NULL, conv_str, sz, sizeof(conv_str),
-                            STR_TERMINATE | STR_NOALIGN);
-       regval_ctr_addvalue(ctr, val_name, REG_SZ, 
-                           (char *) conv_str, str_size);
-}
-
-static void map_dword_into_ctr(REGVAL_CTR *ctr, const char *val_name, 
-                              uint32 dword)
-{
-       regval_ctr_delvalue(ctr, val_name);
-       regval_ctr_addvalue(ctr, val_name, REG_DWORD,
-                           (char *) &dword, sizeof(dword));
-}
-
-static void map_bool_into_ctr(REGVAL_CTR *ctr, const char *val_name,
-                             BOOL bool)
-{
-       uint8 bin_bool = (bool ? 1 : 0);
-       regval_ctr_delvalue(ctr, val_name);
-       regval_ctr_addvalue(ctr, val_name, REG_BINARY, 
-                           (char *) &bin_bool, sizeof(bin_bool));
-}
-
-static void map_single_multi_sz_into_ctr(REGVAL_CTR *ctr, const char *val_name,
-                                        const char *multi_sz)
-{
-       smb_ucs2_t *conv_strs = NULL;
-       size_t str_size;
-
-       /* a multi-sz has to have a null string terminator, i.e., the last
-          string must be followed by two nulls */
-       str_size = (strlen(multi_sz) + 2) * sizeof(smb_ucs2_t);
-       conv_strs = calloc(str_size, 1);
-
-       push_ucs2(NULL, conv_strs, multi_sz, str_size, 
-                 STR_TERMINATE | STR_NOALIGN);
-
-       regval_ctr_delvalue(ctr, val_name);
-       regval_ctr_addvalue(ctr, val_name, REG_MULTI_SZ, 
-                           (char *) conv_strs, str_size);      
-       safe_free(conv_strs);
-       
-}
-
-/****************************************************************************
- * Map the NT_PRINTER_INFO_LEVEL_2 data into DsSpooler keys for publishing.
- *
- * @param info2 NT_PRINTER_INFO_LEVEL_2 describing printer - gets modified
- * @return BOOL indicating success or failure
- ***************************************************************************/
-
-static BOOL map_nt_printer_info2_to_dsspooler(NT_PRINTER_INFO_LEVEL_2 *info2)
-{
-       REGVAL_CTR *ctr = NULL;
-       fstring longname;
-       char *allocated_string = NULL;
-        const char *ascii_str;
-       int i;
-
-       if ((i = lookup_printerkey(&info2->data, SPOOL_DSSPOOLER_KEY)) < 0)
-               i = add_new_printer_key(&info2->data, SPOOL_DSSPOOLER_KEY);
-       ctr = &info2->data.keys[i].values;
-
-       map_sz_into_ctr(ctr, SPOOL_REG_PRINTERNAME, info2->sharename);
-       map_sz_into_ctr(ctr, SPOOL_REG_SHORTSERVERNAME, lp_netbios_name());
-
-       get_myfullname(longname);
-       map_sz_into_ctr(ctr, SPOOL_REG_SERVERNAME, longname);
-
-       asprintf(&allocated_string, "\\\\%s\\%s", longname, info2->sharename);
-       map_sz_into_ctr(ctr, SPOOL_REG_UNCNAME, allocated_string);
-       SAFE_FREE(allocated_string);
-
-       map_dword_into_ctr(ctr, SPOOL_REG_VERSIONNUMBER, 4);
-       map_sz_into_ctr(ctr, SPOOL_REG_DRIVERNAME, info2->drivername);
-       map_sz_into_ctr(ctr, SPOOL_REG_LOCATION, info2->location);
-       map_sz_into_ctr(ctr, SPOOL_REG_DESCRIPTION, info2->comment);
-       map_single_multi_sz_into_ctr(ctr, SPOOL_REG_PORTNAME, info2->portname);
-       map_sz_into_ctr(ctr, SPOOL_REG_PRINTSEPARATORFILE, info2->sepfile);
-       map_dword_into_ctr(ctr, SPOOL_REG_PRINTSTARTTIME, info2->starttime);
-       map_dword_into_ctr(ctr, SPOOL_REG_PRINTENDTIME, info2->untiltime);
-       map_dword_into_ctr(ctr, SPOOL_REG_PRIORITY, info2->priority);
-
-       map_bool_into_ctr(ctr, SPOOL_REG_PRINTKEEPPRINTEDJOBS,
-                         (info2->attributes & 
-                          PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS));
-
-       switch (info2->attributes & 0x3) {
-       case 0:
-               ascii_str = SPOOL_REGVAL_PRINTWHILESPOOLING;
-               break;
-       case 1:
-               ascii_str = SPOOL_REGVAL_PRINTAFTERSPOOLED;
-               break;
-       case 2:
-               ascii_str = SPOOL_REGVAL_PRINTDIRECT;
-               break;
-       default:
-               ascii_str = "unknown";
-       }
-       map_sz_into_ctr(ctr, SPOOL_REG_PRINTSPOOLING, ascii_str);
-
-       return True;
-}
-
-#ifdef HAVE_ADS
-static void store_printer_guid(NT_PRINTER_INFO_LEVEL_2 *info2, GUID guid)
-{
-       int i;
-       REGVAL_CTR *ctr=NULL;
-
-       /* find the DsSpooler key */
-       if ((i = lookup_printerkey(&info2->data, SPOOL_DSSPOOLER_KEY)) < 0)
-               i = add_new_printer_key(&info2->data, SPOOL_DSSPOOLER_KEY);
-       ctr = &info2->data.keys[i].values;
-
-       regval_ctr_delvalue(ctr, "objectGUID");
-       regval_ctr_addvalue(ctr, "objectGUID", REG_BINARY, 
-                           (char *) &guid, sizeof(GUID));      
-}
-
-static WERROR publish_it(NT_PRINTER_INFO_LEVEL *printer)
-{
-       ADS_STATUS ads_rc;
-       TALLOC_CTX *ctx = talloc_init("publish_it");
-       ADS_MODLIST mods = ads_init_mods(ctx);
-       char *prt_dn = NULL, *srv_dn, **srv_cn;
-       void *res = NULL;
-       ADS_STRUCT *ads;
-       const char *attrs[] = {"objectGUID", NULL};
-       GUID guid;
-       WERROR win_rc = WERR_OK;
-
-       ZERO_STRUCT(guid);
-       /* set the DsSpooler info and attributes */
-       if (!(map_nt_printer_info2_to_dsspooler(printer->info_2)))
-                       return WERR_NOMEM;
-       printer->info_2->attributes |= PRINTER_ATTRIBUTE_PUBLISHED;
-       win_rc = mod_a_printer(*printer, 2);
-       if (!W_ERROR_IS_OK(win_rc)) {
-               DEBUG(3, ("err %d saving data\n",
-                                 W_ERROR_V(win_rc)));
-               return win_rc;
-       }
-
-       /* Build the ads mods */
-       get_local_printer_publishing_data(ctx, &mods, 
-                                         &printer->info_2->data);
-       ads_mod_str(ctx, &mods, SPOOL_REG_PRINTERNAME, 
-                   printer->info_2->sharename);
-
-       /* connect to the ADS server */
-       ads = ads_init(NULL, NULL, lp_ads_server());
-       if (!ads) {
-               DEBUG(3, ("ads_init() failed\n"));
-               return WERR_SERVER_UNAVAILABLE;
-       }
-       ads_rc = ads_connect(ads);
-       if (!ADS_ERR_OK(ads_rc)) {
-               DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc)));
-               ads_destroy(&ads);
-               return WERR_ACCESS_DENIED;
-       }
-
-       /* figure out where to publish */
-       ads_find_machine_acct(ads, &res, lp_netbios_name());
-       srv_dn = ldap_get_dn(ads->ld, res);
-       ads_msgfree(ads, res);
-       srv_cn = ldap_explode_dn(srv_dn, 1);
-       asprintf(&prt_dn, "cn=%s-%s,%s", srv_cn[0], 
-                printer->info_2->sharename, srv_dn);
-       ads_memfree(ads, srv_dn);
-
-       /* publish it */
-       ads_rc = ads_add_printer_entry(ads, prt_dn, ctx, &mods);
-       if (LDAP_ALREADY_EXISTS == ads_rc.err.rc)
-               ads_rc = ads_mod_printer_entry(ads, prt_dn, ctx,&mods);
-       
-       /* retreive the guid and store it locally */
-       if (ADS_ERR_OK(ads_search_dn(ads, &res, prt_dn, attrs))) {
-               ads_memfree(ads, prt_dn);
-               ads_pull_guid(ads, res, &guid);
-               ads_msgfree(ads, res);
-               store_printer_guid(printer->info_2, guid);
-               win_rc = mod_a_printer(*printer, 2);
-       } 
-
-       safe_free(prt_dn);
-       ads_destroy(&ads);
-
-       return WERR_OK;
-}
-
-WERROR unpublish_it(NT_PRINTER_INFO_LEVEL *printer)
-{
-       ADS_STATUS ads_rc;
-       ADS_STRUCT *ads;
-       void *res;
-       char *prt_dn = NULL;
-       WERROR win_rc;
-
-       printer->info_2->attributes ^= PRINTER_ATTRIBUTE_PUBLISHED;
-       win_rc = mod_a_printer(*printer, 2);
-       if (!W_ERROR_IS_OK(win_rc)) {
-               DEBUG(3, ("err %d saving data\n",
-                                 W_ERROR_V(win_rc)));
-               return win_rc;
-       }
-       
-       ads = ads_init(NULL, NULL, lp_ads_server());
-       if (!ads) {
-               DEBUG(3, ("ads_init() failed\n"));
-               return WERR_SERVER_UNAVAILABLE;
-       }
-       ads_rc = ads_connect(ads);
-       if (!ADS_ERR_OK(ads_rc)) {
-               DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc)));
-               ads_destroy(&ads);
-               return WERR_ACCESS_DENIED;
-       }
-       
-       /* remove the printer from the directory */
-       ads_rc = ads_find_printer_on_server(ads, &res, 
-                           printer->info_2->sharename, lp_netbios_name());
-       if (ADS_ERR_OK(ads_rc) && ads_count_replies(ads, res)) {
-               prt_dn = ads_get_dn(ads, res);
-               ads_msgfree(ads, res);
-               ads_rc = ads_del_dn(ads, prt_dn);
-               ads_memfree(ads, prt_dn);
-       }
-
-       ads_destroy(&ads);
-       return WERR_OK;
-}
-
-/****************************************************************************
- * Publish a printer in the directory
- *
- * @param snum describing printer service
- * @return WERROR indicating status of publishing
- ***************************************************************************/
-
-WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action)
-{
-       NT_PRINTER_INFO_LEVEL *printer = NULL;
-       WERROR win_rc;
-
-       win_rc = get_a_printer(print_hnd, &printer, 2, lp_servicename(snum));
-       if (!W_ERROR_IS_OK(win_rc))
-               return win_rc;
-
-       switch(action) {
-       case SPOOL_DS_PUBLISH:
-       case SPOOL_DS_UPDATE:
-               win_rc = publish_it(printer);
-               break;
-       case SPOOL_DS_UNPUBLISH:
-               win_rc = unpublish_it(printer);
-               break;
-       default:
-               win_rc = WERR_NOT_SUPPORTED;
-       }
-       
-
-       free_a_printer(&printer, 2);
-       return win_rc;
-}
-
-BOOL is_printer_published(Printer_entry *print_hnd, int snum, GUID *guid)
-{
-       NT_PRINTER_INFO_LEVEL *printer = NULL;
-       REGVAL_CTR *ctr;
-       REGISTRY_VALUE *guid_val;
-       WERROR win_rc;
-       int i;
-
-
-       win_rc = get_a_printer(print_hnd, &printer, 2, lp_servicename(snum));
-       if (!W_ERROR_IS_OK(win_rc))
-               return False;
-
-       if (!(printer->info_2->attributes & PRINTER_ATTRIBUTE_PUBLISHED))
-               return False;
-
-       if ((i = lookup_printerkey(&printer->info_2->data, 
-                                  SPOOL_DSSPOOLER_KEY)) < 0)
-               return False;
-
-       if (!(ctr = &printer->info_2->data.keys[i].values)) {
-               return False;
-       }
-
-       if (!(guid_val = regval_ctr_getvalue(ctr, "objectGUID"))) {
-               return False;
-       }
-
-       if (regval_size(guid_val) == sizeof(GUID))
-               memcpy(guid, regval_data_p(guid_val), sizeof(GUID));
-
-       return True;
-}
-       
-#else
-WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action)
-{
-       return WERR_OK;
-}
-BOOL is_printer_published(Printer_entry *print_hnd, int snum, GUID *guid)
-{
-       return False;
-}
-#endif
-/****************************************************************************
- ***************************************************************************/
-WERROR delete_all_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key )
-{
-       NT_PRINTER_DATA *data;
-       int             i;
-       int             removed_keys = 0;
-       int             empty_slot;
-       
-       data = &p2->data;
-       empty_slot = data->num_keys;
-
-       if ( !key )
-               return WERR_INVALID_PARAM;
-       
-       /* remove all keys */
-
-       if ( !strlen(key) ) {
-               for ( i=0; i<data->num_keys; i++ ) {
-                       DEBUG(8,("delete_all_printer_data: Removed all Printer Data from key [%s]\n",
-                               data->keys[i].name));
-               
-                       SAFE_FREE( data->keys[i].name );
-                       regval_ctr_destroy( &data->keys[i].values );
-               }
-       
-               DEBUG(8,("delete_all_printer_data: Removed all Printer Data from printer [%s]\n",
-                       p2->printername ));
-       
-               SAFE_FREE( data->keys );
-               ZERO_STRUCTP( data );
-
-               return WERR_OK;
-       }
-
-       /* remove a specific key (and all subkeys) */
-       
-       for ( i=0; i<data->num_keys; i++ ) {
-               if ( StrnCaseCmp( data->keys[i].name, key, strlen(key)) == 0 ) {
-                       DEBUG(8,("delete_all_printer_data: Removed all Printer Data from key [%s]\n",
-                               data->keys[i].name));
-               
-                       SAFE_FREE( data->keys[i].name );
-                       regval_ctr_destroy( &data->keys[i].values );
-               
-                       /* mark the slot as empty */
-
-                       ZERO_STRUCTP( &data->keys[i] );
-               }
-       }
-
-       /* find the first empty slot */
-
-       for ( i=0; i<data->num_keys; i++ ) {
-               if ( !data->keys[i].name ) {
-                       empty_slot = i;
-                       removed_keys++;
-                       break;
-               }
-       }
-
-       if ( i == data->num_keys )
-               /* nothing was removed */
-               return WERR_INVALID_PARAM;
-
-       /* move everything down */
-       
-       for ( i=empty_slot+1; i<data->num_keys; i++ ) {
-               if ( data->keys[i].name ) {
-                       memcpy( &data->keys[empty_slot], &data->keys[i], sizeof(NT_PRINTER_KEY) ); 
-                       ZERO_STRUCTP( &data->keys[i] );
-                       empty_slot++;
-                       removed_keys++;
-               }
-       }
-
-       /* update count */
-               
-       data->num_keys -= removed_keys;
-
-       /* sanity check to see if anything is left */
-
-       if ( !data->num_keys ) {
-               DEBUG(8,("delete_all_printer_data: No keys left for printer [%s]\n", p2->printername ));
-
-               SAFE_FREE( data->keys );
-               ZERO_STRUCTP( data );
-       }
-
-       return WERR_OK;
-}
-
-/****************************************************************************
- ***************************************************************************/
-WERROR delete_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const char *value )
-{
-       WERROR          result = WERR_OK;
-       int             key_index;
-       
-       /* we must have names on non-zero length */
-       
-       if ( !key || !*key|| !value || !*value )
-               return WERR_INVALID_NAME;
-               
-       /* find the printer key first */
-
-       key_index = lookup_printerkey( &p2->data, key );
-       if ( key_index == -1 )
-               return WERR_OK;
-               
-       regval_ctr_delvalue( &p2->data.keys[key_index].values, value );
-       
-       DEBUG(8,("delete_printer_data: Removed key => [%s], value => [%s]\n",
-               key, value ));
-       
-       return result;
-}
-
-/****************************************************************************
- ***************************************************************************/
-WERROR add_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const char *value, 
-                           uint32 type, uint8 *data, int real_len )
-{
-       WERROR          result = WERR_OK;
-       int             key_index;
-
-       /* we must have names on non-zero length */
-       
-       if ( !key || !*key|| !value || !*value )
-               return WERR_INVALID_NAME;
-               
-       /* find the printer key first */
-       
-       key_index = lookup_printerkey( &p2->data, key );
-       if ( key_index == -1 )
-               key_index = add_new_printer_key( &p2->data, key );
-               
-       if ( key_index == -1 )
-               return WERR_NOMEM;
-       
-       regval_ctr_addvalue( &p2->data.keys[key_index].values, value,
-               type, data, real_len );
-       
-       DEBUG(8,("add_printer_data: Added key => [%s], value => [%s], type=> [%d], size => [%d]\n",
-               key, value, type, real_len  ));
-       
-       return result;
-}
-
-/****************************************************************************
- ***************************************************************************/
-REGISTRY_VALUE* get_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const char *value )
-{
-       int             key_index;
-
-       if ( (key_index = lookup_printerkey( &p2->data, key )) == -1 )
-               return NULL;
-
-       DEBUG(8,("get_printer_data: Attempting to lookup key => [%s], value => [%s]\n",
-               key, value ));
-
-       return regval_ctr_getvalue( &p2->data.keys[key_index].values, value );
-}
-
-/****************************************************************************
- Unpack a list of registry values frem the TDB
- ***************************************************************************/
-static int unpack_values(NT_PRINTER_DATA *printer_data, char *buf, int buflen)
-{
-       int             len = 0;
-       uint32          type;
-       pstring         string, valuename, keyname;
-       char            *str;
-       int             size;
-       uint8           *data_p;
-       REGISTRY_VALUE  *regval_p;
-       int             key_index;
-       
-       /* add the "PrinterDriverData" key first for performance reasons */
-       
-       add_new_printer_key( printer_data, SPOOL_PRINTERDATA_KEY );
-
-       /* loop and unpack the rest of the registry values */
-       
-       while ( True ) {
-       
-               /* check to see if there are any more registry values */
-               
-               len += tdb_unpack(buf+len, buflen-len, "p", &regval_p);         
-               if ( !regval_p ) 
-                       break;
-
-               /* unpack the next regval */
-               
-               len += tdb_unpack(buf+len, buflen-len, "fdB",
-                                 string,
-                                 &type,
-                                 &size,
-                                 &data_p);
-       
-               /*
-                * break of the keyname from the value name.  
-                * Should only be one '\' in the string returned.
-                */     
-                
-               str = strrchr( string, '\\');
-               
-               /* Put in "PrinterDriverData" is no key specified */
-               
-               if ( !str ) {
-                       pstrcpy( keyname, SPOOL_PRINTERDATA_KEY );
-                       pstrcpy( valuename, string );
-               }
-               else {
-                       *str = '\0';
-                       pstrcpy( keyname, string );
-                       pstrcpy( valuename, str+1 );
-               }
-                       
-               /* see if we need a new key */
-               
-               if ( (key_index=lookup_printerkey( printer_data, keyname )) == -1 )
-                       key_index = add_new_printer_key( printer_data, keyname );
-                       
-               if ( key_index == -1 ) {
-                       DEBUG(0,("unpack_values: Failed to allocate a new key [%s]!\n",
-                               keyname));
-                       break;
-               }
-               
-               /* add the new value */
-               
-               regval_ctr_addvalue( &printer_data->keys[key_index].values, valuename, type, data_p, size );
-
-               SAFE_FREE(data_p); /* 'B' option to tdbpack does a malloc() */
-
-               DEBUG(8,("specific: [%s:%s], len: %d\n", keyname, valuename, size));
-       }
-
-       return len;
-}
-
-/****************************************************************************
- ***************************************************************************/
-
-static void map_to_os2_driver(fstring drivername)
-{
-       static BOOL initialised=False;
-       static fstring last_from,last_to;
-       char *mapfile = lp_os2_driver_map();
-       char **lines = NULL;
-       int numlines = 0;
-       int i;
-
-       if (!strlen(drivername))
-               return;
-
-       if (!*mapfile)
-               return;
-
-       if (!initialised) {
-               *last_from = *last_to = 0;
-               initialised = True;
-       }
-
-       if (strequal(drivername,last_from)) {
-               DEBUG(3,("Mapped Windows driver %s to OS/2 driver %s\n",drivername,last_to));
-               fstrcpy(drivername,last_to);
-               return;
-       }
-
-       lines = file_lines_load(mapfile, &numlines);
-       if (numlines == 0) {
-               DEBUG(0,("No entries in OS/2 driver map %s\n",mapfile));
-               return;
-       }
-
-       DEBUG(4,("Scanning OS/2 driver map %s\n",mapfile));
-
-       for( i = 0; i < numlines; i++) {
-               char *nt_name = lines[i];
-               char *os2_name = strchr(nt_name,'=');
-
-               if (!os2_name)
-                       continue;
-
-               *os2_name++ = 0;
-
-               while (isspace(*nt_name))
-                       nt_name++;
-
-               if (!*nt_name || strchr("#;",*nt_name))
-                       continue;
-
-               {
-                       int l = strlen(nt_name);
-                       while (l && isspace(nt_name[l-1])) {
-                               nt_name[l-1] = 0;
-                               l--;
-                       }
-               }
-
-               while (isspace(*os2_name))
-                       os2_name++;
-
-               {
-                       int l = strlen(os2_name);
-                       while (l && isspace(os2_name[l-1])) {
-                               os2_name[l-1] = 0;
-                               l--;
-                       }
-               }
-
-               if (strequal(nt_name,drivername)) {
-                       DEBUG(3,("Mapped windows driver %s to os2 driver%s\n",drivername,os2_name));
-                       fstrcpy(last_from,drivername);
-                       fstrcpy(last_to,os2_name);
-                       fstrcpy(drivername,os2_name);
-                       file_lines_free(lines);
-                       return;
-               }
-       }
-
-       file_lines_free(lines);
-}
-
-/****************************************************************************
- Get a default printer info 2 struct.
-****************************************************************************/
-static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, const char *sharename)
-{
-       int snum;
-       NT_PRINTER_INFO_LEVEL_2 info;
-
-       ZERO_STRUCT(info);
-
-       snum = lp_servicenumber(sharename);
-
-       slprintf(info.servername, sizeof(info.servername)-1, "\\\\%s", get_called_name());
-       slprintf(info.printername, sizeof(info.printername)-1, "\\\\%s\\%s", 
-                get_called_name(), sharename);
-       fstrcpy(info.sharename, sharename);
-       fstrcpy(info.portname, SAMBA_PRINTER_PORT_NAME);
-
-       /* by setting the driver name to an empty string, a local NT admin
-          can now run the **local** APW to install a local printer driver
-          for a Samba shared printer in 2.2.  Without this, drivers **must** be 
-          installed on the Samba server for NT clients --jerry */
-#if 0  /* JERRY --do not uncomment-- */
-       if (!*info.drivername)
-               fstrcpy(info.drivername, "NO DRIVER AVAILABLE FOR THIS PRINTER");
-#endif
-
-
-       DEBUG(10,("get_a_printer_2_default: driver name set to [%s]\n", info.drivername));
-
-       pstrcpy(info.comment, "");
-       fstrcpy(info.printprocessor, "winprint");
-       fstrcpy(info.datatype, "RAW");
-
-       info.attributes = PRINTER_ATTRIBUTE_SAMBA;
-
-       info.starttime = 0; /* Minutes since 12:00am GMT */
-       info.untiltime = 0; /* Minutes since 12:00am GMT */
-       info.priority = 1;
-       info.default_priority = 1;
-       info.setuptime = (uint32)time(NULL);
-
-       /*
-        * I changed this as I think it is better to have a generic
-        * DEVMODE than to crash Win2k explorer.exe   --jerry
-        * See the HP Deskjet 990c Win2k drivers for an example.
-        *
-        * However the default devmode appears to cause problems
-        * with the HP CLJ 8500 PCL driver.  Hence the addition of
-        * the "default devmode" parameter   --jerry 22/01/2002
-        */
-
-       if (lp_default_devmode(snum)) {
-               if ((info.devmode = construct_nt_devicemode(info.printername)) == NULL)
-                       goto fail;
-       }
-       else {
-               info.devmode = NULL;
-       }
-
-       /* This will get the current RPC talloc context, but we should be
-          passing this as a parameter... fixme... JRA ! */
-
-       if (!nt_printing_getsec(get_talloc_ctx(), sharename, &info.secdesc_buf))
-               goto fail;
-
-       *info_ptr = (NT_PRINTER_INFO_LEVEL_2 *)memdup(&info, sizeof(info));
-       if (! *info_ptr) {
-               DEBUG(0,("get_a_printer_2_default: malloc fail.\n"));
-               goto fail;
-       }
-
-       return WERR_OK;
-
-  fail:
-       if (info.devmode)
-               free_nt_devicemode(&info.devmode);
-       return WERR_ACCESS_DENIED;
-}
-
-/****************************************************************************
-****************************************************************************/
-static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, const char *sharename)
-{
-       pstring key;
-       NT_PRINTER_INFO_LEVEL_2 info;
-       int             len = 0;
-       TDB_DATA kbuf, dbuf;
-       fstring printername;
-               
-       ZERO_STRUCT(info);
-
-       slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, sharename);
-
-       kbuf.dptr = key;
-       kbuf.dsize = strlen(key)+1;
-
-       dbuf = tdb_fetch(tdb_printers, kbuf);
-       if (!dbuf.dptr)
-               return get_a_printer_2_default(info_ptr, sharename);
-
-       len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "dddddddddddfffffPfffff",
-                       &info.attributes,
-                       &info.priority,
-                       &info.default_priority,
-                       &info.starttime,
-                       &info.untiltime,
-                       &info.status,
-                       &info.cjobs,
-                       &info.averageppm,
-                       &info.changeid,
-                       &info.c_setprinter,
-                       &info.setuptime,
-                       info.servername,
-                       info.printername,
-                       info.sharename,
-                       info.portname,
-                       info.drivername,
-                       info.comment,
-                       info.location,
-                       info.sepfile,
-                       info.printprocessor,
-                       info.datatype,
-                       info.parameters);
-
-       /* Samba has to have shared raw drivers. */
-       info.attributes |= PRINTER_ATTRIBUTE_SAMBA;
-
-       /* Restore the stripped strings. */
-       slprintf(info.servername, sizeof(info.servername)-1, "\\\\%s", get_called_name());
-       slprintf(printername, sizeof(printername)-1, "\\\\%s\\%s", get_called_name(),
-                       info.printername);
-       fstrcpy(info.printername, printername);
-
-       len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
-
-       /*
-        * Some client drivers freak out if there is a NULL devmode
-        * (probably the driver is not checking before accessing 
-        * the devmode pointer)   --jerry
-        *
-        * See comments in get_a_printer_2_default()
-        */
-
-       if (lp_default_devmode(lp_servicenumber(sharename)) && !info.devmode) {
-               DEBUG(8,("get_a_printer_2: Constructing a default device mode for [%s]\n",
-                       printername));
-               info.devmode = construct_nt_devicemode(printername);
-       }
-
-       len += unpack_values( &info.data, dbuf.dptr+len, dbuf.dsize-len );
-
-       /* This will get the current RPC talloc context, but we should be
-          passing this as a parameter... fixme... JRA ! */
-
-       nt_printing_getsec(get_talloc_ctx(), sharename, &info.secdesc_buf);
-
-       /* Fix for OS/2 drivers. */
-
-       if (get_remote_arch() == RA_OS2)
-               map_to_os2_driver(info.drivername);
-
-       SAFE_FREE(dbuf.dptr);
-       *info_ptr=memdup(&info, sizeof(info));
-
-       DEBUG(9,("Unpacked printer [%s] name [%s] running driver [%s]\n",
-                sharename, info.printername, info.drivername));
-
-       return WERR_OK; 
-}
-
-/****************************************************************************
- Debugging function, dump at level 6 the struct in the logs.
-****************************************************************************/
-static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
-{
-       uint32 result;
-       NT_PRINTER_INFO_LEVEL_2 *info2;
-       
-       DEBUG(106,("Dumping printer at level [%d]\n", level));
-       
-       switch (level) {
-               case 2:
-               {
-                       if (printer.info_2 == NULL)
-                               result=5;
-                       else
-                       {
-                               info2=printer.info_2;
-                       
-                               DEBUGADD(106,("attributes:[%d]\n", info2->attributes));
-                               DEBUGADD(106,("priority:[%d]\n", info2->priority));
-                               DEBUGADD(106,("default_priority:[%d]\n", info2->default_priority));
-                               DEBUGADD(106,("starttime:[%d]\n", info2->starttime));
-                               DEBUGADD(106,("untiltime:[%d]\n", info2->untiltime));
-                               DEBUGADD(106,("status:[%d]\n", info2->status));
-                               DEBUGADD(106,("cjobs:[%d]\n", info2->cjobs));
-                               DEBUGADD(106,("averageppm:[%d]\n", info2->averageppm));
-                               DEBUGADD(106,("changeid:[%d]\n", info2->changeid));
-                               DEBUGADD(106,("c_setprinter:[%d]\n", info2->c_setprinter));
-                               DEBUGADD(106,("setuptime:[%d]\n", info2->setuptime));
-
-                               DEBUGADD(106,("servername:[%s]\n", info2->servername));
-                               DEBUGADD(106,("printername:[%s]\n", info2->printername));
-                               DEBUGADD(106,("sharename:[%s]\n", info2->sharename));
-                               DEBUGADD(106,("portname:[%s]\n", info2->portname));
-                               DEBUGADD(106,("drivername:[%s]\n", info2->drivername));
-                               DEBUGADD(106,("comment:[%s]\n", info2->comment));
-                               DEBUGADD(106,("location:[%s]\n", info2->location));
-                               DEBUGADD(106,("sepfile:[%s]\n", info2->sepfile));
-                               DEBUGADD(106,("printprocessor:[%s]\n", info2->printprocessor));
-                               DEBUGADD(106,("datatype:[%s]\n", info2->datatype));
-                               DEBUGADD(106,("parameters:[%s]\n", info2->parameters));
-                               result=0;
-                       }
-                       break;
-               }
-               default:
-                       DEBUGADD(106,("dump_a_printer: Level %u not implemented\n", (unsigned int)level ));
-                       result=1;
-                       break;
-       }
-       
-       return result;
-}
-
-/****************************************************************************
- Update the changeid time.
- This is SO NASTY as some drivers need this to change, others need it
- static. This value will change every second, and I must hope that this
- is enough..... DON'T CHANGE THIS CODE WITHOUT A TEST MATRIX THE SIZE OF
- UTAH ! JRA.
-****************************************************************************/
-
-static uint32 rev_changeid(void)
-{
-       struct timeval tv;
-
-       get_process_uptime(&tv);
-
-#if 1  /* JERRY */
-       /* Return changeid as msec since spooler restart */
-       return tv.tv_sec * 1000 + tv.tv_usec / 1000;
-#else
-       /*
-        * This setting seems to work well but is too untested
-        * to replace the above calculation.  Left in for experiementation
-        * of the reader            --jerry (Tue Mar 12 09:15:05 CST 2002)
-        */
-       return tv.tv_sec * 10 + tv.tv_usec / 100000;
-#endif
-}
-
-/*
- * The function below are the high level ones.
- * only those ones must be called from the spoolss code.
- * JFM.
- */
-
-/****************************************************************************
- Modify a printer. This is called from SETPRINTERDATA/DELETEPRINTERDATA.
-****************************************************************************/
-
-WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
-{
-       WERROR result;
-       
-       dump_a_printer(printer, level); 
-       
-       /* 
-        * invalidate cache for all open handles to this printer.
-        * cache for a given handle will be updated on the next 
-        * get_a_printer() 
-        */
-        
-       invalidate_printer_hnd_cache( printer.info_2->sharename );
-       
-       switch (level) {
-               case 2:
-               {
-                       /*
-                        * Update the changestamp.  Emperical tests show that the
-                        * ChangeID is always updated,but c_setprinter is  
-                        *  global spooler variable (not per printer).
-                        */
-
-                       /* ChangeID **must** be increasing over the lifetime
-                          of client's spoolss service in order for the
-                          client's cache to show updates */
-
-                       printer.info_2->changeid = rev_changeid();
-
-                       /*
-                        * Because one day someone will ask:
-                        * NT->NT       An admin connection to a remote
-                        *              printer show changes imeediately in
-                        *              the properities dialog
-                        *      
-                        *              A non-admin connection will only show the
-                        *              changes after viewing the properites page
-                        *              2 times.  Seems to be related to a
-                        *              race condition in the client between the spooler
-                        *              updating the local cache and the Explorer.exe GUI
-                        *              actually displaying the properties.
-                        *
-                        *              This is fixed in Win2k.  admin/non-admin
-                        *              connections both display changes immediately.
-                        *
-                        * 14/12/01     --jerry
-                        */
-
-                       result=update_a_printer_2(printer.info_2);
-                       
-                       break;
-               }
-               default:
-                       result=WERR_UNKNOWN_LEVEL;
-                       break;
-       }
-       
-       return result;
-}
-
-/****************************************************************************
- Initialize printer devmode & data with previously saved driver init values.
-****************************************************************************/
-
-static BOOL set_driver_init_2( NT_PRINTER_INFO_LEVEL_2 *info_ptr )
-{
-       int                     len = 0;
-       pstring                 key;
-       TDB_DATA                kbuf, dbuf;
-       NT_PRINTER_INFO_LEVEL_2 info;
-
-
-       ZERO_STRUCT(info);
-
-       /*
-        * Delete any printer data 'values' already set. When called for driver
-        * replace, there will generally be some, but during an add printer, there
-        * should not be any (if there are delete them).
-        */
-        
-       delete_all_printer_data( info_ptr, "" );
-       
-       slprintf(key, sizeof(key)-1, "%s%s", DRIVER_INIT_PREFIX, info_ptr->drivername);
-
-       kbuf.dptr = key;
-       kbuf.dsize = strlen(key)+1;
-
-       dbuf = tdb_fetch(tdb_drivers, kbuf);
-       if (!dbuf.dptr) {
-               /*
-                * When changing to a driver that has no init info in the tdb, remove
-                * the previous drivers init info and leave the new on blank.
-                */
-               free_nt_devicemode(&info_ptr->devmode);
-               return False;
-       }
-       
-       /*
-        * Get the saved DEVMODE..
-        */
-        
-       len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
-
-       /*
-        * The saved DEVMODE contains the devicename from the printer used during
-        * the initialization save. Change it to reflect the new printer.
-        */
-        
-       if ( info.devmode ) {
-               ZERO_STRUCT(info.devmode->devicename);
-               fstrcpy(info.devmode->devicename, info_ptr->printername);
-       }
-
-       /*
-        * NT/2k does not change out the entire DeviceMode of a printer
-        * when changing the driver.  Only the driverextra, private, & 
-        * driverversion fields.   --jerry  (Thu Mar 14 08:58:43 CST 2002)
-        *
-        * Later examination revealed that Windows NT/2k does reset the
-        * the printer's device mode, bit **only** when you change a 
-        * property of the device mode such as the page orientation.
-        * --jerry
-        */
-
-
-       /* Bind the saved DEVMODE to the new the printer */
-        
-       free_nt_devicemode(&info_ptr->devmode);
-       info_ptr->devmode = info.devmode;
-
-       DEBUG(10,("set_driver_init_2: Set printer [%s] init %s DEVMODE for driver [%s]\n",
-               info_ptr->printername, info_ptr->devmode?"VALID":"NULL", info_ptr->drivername));
-
-       /* Add the printer data 'values' to the new printer */
-        
-       len += unpack_values( &info_ptr->data, dbuf.dptr+len, dbuf.dsize-len );
-       
-
-       SAFE_FREE(dbuf.dptr);
-
-       return True;    
-}
-
-/****************************************************************************
- Initialize printer devmode & data with previously saved driver init values.
- When a printer is created using AddPrinter, the drivername bound to the
- printer is used to lookup previously saved driver initialization info, which
- is bound to the new printer.
-****************************************************************************/
-
-BOOL set_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
-{
-       BOOL result = False;
-       
-       switch (level) {
-               case 2:
-                       result = set_driver_init_2(printer->info_2);
-                       break;
-                       
-               default:
-                       DEBUG(0,("set_driver_init: Programmer's error!  Unknown driver_init level [%d]\n",
-                               level));
-                       break;
-       }
-       
-       return result;
-}
-
-/****************************************************************************
- Delete driver init data stored for a specified driver
-****************************************************************************/
-
-BOOL del_driver_init(char *drivername)
-{
-       pstring key;
-       TDB_DATA kbuf;
-
-       if (!drivername || !*drivername) {
-               DEBUG(3,("del_driver_init: No drivername specified!\n"));
-               return False;
-       }
-
-       slprintf(key, sizeof(key)-1, "%s%s", DRIVER_INIT_PREFIX, drivername);
-
-       kbuf.dptr = key;
-       kbuf.dsize = strlen(key)+1;
-
-       DEBUG(6,("del_driver_init: Removing driver init data for [%s]\n", drivername));
-
-       return (tdb_delete(tdb_drivers, kbuf) == 0);
-}
-
-/****************************************************************************
- Pack up the DEVMODE and values for a printer into a 'driver init' entry 
- in the tdb. Note: this is different from the driver entry and the printer
- entry. There should be a single driver init entry for each driver regardless
- of whether it was installed from NT or 2K. Technically, they should be
- different, but they work out to the same struct.
-****************************************************************************/
-
-static uint32 update_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info)
-{
-       pstring key;
-       char *buf;
-       int buflen, len, ret;
-       TDB_DATA kbuf, dbuf;
-
-       buf = NULL;
-       buflen = 0;
-
- again:        
-       len = 0;
-       len += pack_devicemode(info->devmode, buf+len, buflen-len);
-
-       len += pack_values( &info->data, buf+len, buflen-len );
-
-       if (buflen != len) {
-               char *tb;
-
-               tb = (char *)Realloc(buf, len);
-               if (!tb) {
-                       DEBUG(0, ("update_driver_init_2: failed to enlarge buffer!\n"));
-                       ret = -1;
-                       goto done;
-               }
-               else
-                       buf = tb;
-               buflen = len;
-               goto again;
-       }
-
-       slprintf(key, sizeof(key)-1, "%s%s", DRIVER_INIT_PREFIX, info->drivername);
-
-       kbuf.dptr = key;
-       kbuf.dsize = strlen(key)+1;
-       dbuf.dptr = buf;
-       dbuf.dsize = len;
-
-       ret = tdb_store(tdb_drivers, kbuf, dbuf, TDB_REPLACE);
-
-done:
-       if (ret == -1)
-               DEBUG(8, ("update_driver_init_2: error updating printer init to tdb on disk\n"));
-
-       SAFE_FREE(buf);
-
-       DEBUG(10,("update_driver_init_2: Saved printer [%s] init DEVMODE & values for driver [%s]\n",
-                info->sharename, info->drivername));
-
-       return ret;
-}
-
-/****************************************************************************
- Update (i.e. save) the driver init info (DEVMODE and values) for a printer
-****************************************************************************/
-
-uint32 update_driver_init(NT_PRINTER_INFO_LEVEL printer, uint32 level)
-{
-       uint32 result;
-       
-       dump_a_printer(printer, level); 
-       
-       switch (level) {
-               case 2:
-                       result = update_driver_init_2(printer.info_2);
-                       break;
-               default:
-                       result = 1;
-                       break;
-       }
-       
-       return result;
-}
-
-/****************************************************************************
- Convert the printer data value, a REG_BINARY array, into an initialization 
- DEVMODE. Note: the array must be parsed as if it was a DEVMODE in an rpc...
- got to keep the endians happy :).
-****************************************************************************/
-
-static BOOL convert_driver_init( TALLOC_CTX *ctx, NT_DEVICEMODE *nt_devmode, uint8 *data, uint32 data_len )
-{
-       BOOL       result = False;
-       prs_struct ps;
-       DEVICEMODE devmode;
-
-       ZERO_STRUCT(devmode);
-
-       prs_init(&ps, 0, ctx, UNMARSHALL);
-       ps.data_p      = (char *)data;
-       ps.buffer_size = data_len;
-
-       if (spoolss_io_devmode("phantom DEVMODE", &ps, 0, &devmode))
-               result = convert_devicemode("", &devmode, &nt_devmode);
-       else
-               DEBUG(10,("convert_driver_init: error parsing DEVMODE\n"));
-
-       return result;
-}
-
-/****************************************************************************
- Set the DRIVER_INIT info in the tdb. Requires Win32 client code that:
-
- 1. Use the driver's config DLL to this UNC printername and:
-    a. Call DrvPrintEvent with PRINTER_EVENT_INITIALIZE
-    b. Call DrvConvertDevMode with CDM_DRIVER_DEFAULT to get default DEVMODE
- 2. Call SetPrinterData with the 'magic' key and the DEVMODE as data.
-
- The last step triggers saving the "driver initialization" information for
- this printer into the tdb. Later, new printers that use this driver will
- have this initialization information bound to them. This simulates the
- driver initialization, as if it had run on the Samba server (as it would
- have done on NT).
-
- The Win32 client side code requirement sucks! But until we can run arbitrary
- Win32 printer driver code on any Unix that Samba runs on, we are stuck with it.
- It would have been easier to use SetPrinter because all the UNMARSHALLING of
- the DEVMODE is done there, but 2K/XP clients do not set the DEVMODE... think
- about it and you will realize why.  JRR 010720
-****************************************************************************/
-
-static WERROR save_driver_init_2(NT_PRINTER_INFO_LEVEL *printer, uint8 *data, uint32 data_len )
-{
-       WERROR        status       = WERR_OK;
-       TALLOC_CTX    *ctx         = NULL;
-       NT_DEVICEMODE *nt_devmode  = NULL;
-       NT_DEVICEMODE *tmp_devmode = printer->info_2->devmode;
-       
-       /*
-        * When the DEVMODE is already set on the printer, don't try to unpack it.
-        */
-       DEBUG(8,("save_driver_init_2: Enter...\n"));
-       
-       if ( !printer->info_2->devmode && data_len ) {
-               /*
-                * Set devmode on printer info, so entire printer initialization can be
-                * saved to tdb.
-                */
-
-               if ((ctx = talloc_init("save_driver_init_2")) == NULL)
-                       return WERR_NOMEM;
-
-               if ((nt_devmode = (NT_DEVICEMODE*)malloc(sizeof(NT_DEVICEMODE))) == NULL) {
-                       status = WERR_NOMEM;
-                       goto done;
-               }
-       
-               ZERO_STRUCTP(nt_devmode);
-
-               /*
-                * The DEVMODE is held in the 'data' component of the param in raw binary.
-                * Convert it to to a devmode structure
-                */
-               if ( !convert_driver_init( ctx, nt_devmode, data, data_len )) {
-                       DEBUG(10,("save_driver_init_2: error converting DEVMODE\n"));
-                       status = WERR_INVALID_PARAM;
-                       goto done;
-               }
-
-               printer->info_2->devmode = nt_devmode;
-       }
-
-       /*
-        * Pack up and add (or update) the DEVMODE and any current printer data to
-        * a 'driver init' element in the tdb
-        * 
-        */
-
-       if ( update_driver_init(*printer, 2) != 0 ) {
-               DEBUG(10,("save_driver_init_2: error updating DEVMODE\n"));
-               status = WERR_NOMEM;
-               goto done;
-       }
-       
-       /*
-        * If driver initialization info was successfully saved, set the current 
-        * printer to match it. This allows initialization of the current printer 
-        * as well as the driver.
-        */
-       status = mod_a_printer(*printer, 2);
-       if (!W_ERROR_IS_OK(status)) {
-               DEBUG(10,("save_driver_init_2: error setting DEVMODE on printer [%s]\n",
-                                 printer->info_2->printername));
-       }
-       
-  done:
-       talloc_destroy(ctx);
-       free_nt_devicemode( &nt_devmode );
-       
-       printer->info_2->devmode = tmp_devmode;
-
-       return status;
-}
-
-/****************************************************************************
- Update the driver init info (DEVMODE and specifics) for a printer
-****************************************************************************/
-
-WERROR save_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level, uint8 *data, uint32 data_len)
-{
-       WERROR status = WERR_OK;
-       
-       switch (level) {
-               case 2:
-                       status = save_driver_init_2( printer, data, data_len );
-                       break;
-               default:
-                       status = WERR_UNKNOWN_LEVEL;
-                       break;
-       }
-       
-       return status;
-}
-
-/****************************************************************************
- Deep copy a NT_PRINTER_DATA
-****************************************************************************/
-
-static NTSTATUS copy_printer_data( NT_PRINTER_DATA *dst, NT_PRINTER_DATA *src )
-{
-       int i, j, num_vals, new_key_index;
-       REGVAL_CTR *src_key, *dst_key;
-       
-       if ( !dst || !src )
-               return NT_STATUS_NO_MEMORY;
-       
-       for ( i=0; i<src->num_keys; i++ ) {
-                          
-               /* create a new instance of the printerkey in the destination 
-                  printer_data object */
-                  
-               new_key_index = add_new_printer_key( dst, src->keys[i].name );
-               dst_key = &dst->keys[new_key_index].values;
-
-               src_key = &src->keys[i].values;
-               num_vals = regval_ctr_numvals( src_key );
-               
-               /* dup the printer entire printer key */
-               
-               for ( j=0; j<num_vals; j++ ) {
-                       regval_ctr_copyvalue( dst_key, regval_ctr_specific_value(src_key, j) );
-               }
-       }
-               
-       return NT_STATUS_OK;
-}
-
-/****************************************************************************
- Deep copy a NT_PRINTER_INFO_LEVEL_2 structure using malloc()'d memeory
- Caller must free.
-****************************************************************************/
-
-static NT_PRINTER_INFO_LEVEL_2* dup_printer_2( TALLOC_CTX *ctx, NT_PRINTER_INFO_LEVEL_2 *printer )
-{
-       NT_PRINTER_INFO_LEVEL_2 *copy;
-       
-       if ( !printer )
-               return NULL;
-       
-       if ( !(copy = (NT_PRINTER_INFO_LEVEL_2 *)malloc(sizeof(NT_PRINTER_INFO_LEVEL_2))) )
-               return NULL;
-               
-       memcpy( copy, printer, sizeof(NT_PRINTER_INFO_LEVEL_2) );
-       
-       /* malloc()'d members copied here */
-       
-       copy->devmode = dup_nt_devicemode( printer->devmode );  
-
-       ZERO_STRUCT( copy->data );
-       copy_printer_data( &copy->data, &printer->data );
-       
-       /* this is talloc()'d; very ugly that we have a structure that 
-          is half malloc()'d and half talloc()'d but that is the way 
-          that the PRINTER_INFO stuff is written right now.  --jerry  */
-          
-       copy->secdesc_buf = dup_sec_desc_buf( ctx, printer->secdesc_buf );
-               
-       return copy;
-}
-
-/****************************************************************************
- Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory.
-****************************************************************************/
-
-#define ENABLE_PRINT_HND_CACHE 1
-
-WERROR get_a_printer( Printer_entry *print_hnd, NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level, 
-                       const char *sharename)
-{
-       WERROR result;
-       NT_PRINTER_INFO_LEVEL *printer = NULL;
-       
-       *pp_printer = NULL;
-
-       DEBUG(10,("get_a_printer: [%s] level %u\n", sharename, (unsigned int)level));
-
-       switch (level) {
-               case 2:
-                       if ((printer = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL))) == NULL) {
-                               DEBUG(0,("get_a_printer: malloc fail.\n"));
-                               return WERR_NOMEM;
-                       }
-                       ZERO_STRUCTP(printer);
-                       
-                       /* 
-                        * check for cache first.  A Printer handle cannot changed
-                        * to another printer object so we only check that the printer 
-                        * is actually for a printer and that the printer_info pointer 
-                        * is valid
-                        */
-#ifdef ENABLE_PRINT_HND_CACHE  /* JERRY */
-                       if ( print_hnd 
-                               && (print_hnd->printer_type==PRINTER_HANDLE_IS_PRINTER) 
-                               && print_hnd->printer_info )
-                       {
-                               if ( !(printer->info_2 = dup_printer_2(print_hnd->ctx, print_hnd->printer_info->info_2)) ) {
-                                       DEBUG(0,("get_a_printer: unable to copy cached printer info!\n"));
-                                       
-                                       SAFE_FREE(printer);
-                                       return WERR_NOMEM;
-                               }
-                               
-                               DEBUG(10,("get_a_printer: using cached copy of printer_info_2\n"));
-                               
-                               *pp_printer = printer;                          
-                               result = WERR_OK;
-                               
-                               break;
-                       }
-#endif 
-
-                       /* no cache; look it up on disk */
-                       
-                       result=get_a_printer_2(&printer->info_2, sharename);
-                       if (W_ERROR_IS_OK(result)) {
-                               dump_a_printer(*printer, level);
-
-#if ENABLE_PRINT_HND_CACHE     /* JERRY */                                                             
-                               /* save a copy in cache */
-                               if ( print_hnd && (print_hnd->printer_type==PRINTER_HANDLE_IS_PRINTER)) {
-                                       if ( !print_hnd->printer_info )
-                                               print_hnd->printer_info = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL));
-                                       
-                                       if ( print_hnd->printer_info ) {
-                                               print_hnd->printer_info->info_2 = dup_printer_2(print_hnd->ctx, printer->info_2);
-                                               
-                                               /* don't fail the lookup just because the cache update failed */
-                                               if ( !print_hnd->printer_info->info_2 )
-                                                       DEBUG(0,("get_a_printer: unable to copy new printer info!\n"));
-                                       }
-                                       
-                               }
-#endif
-                               *pp_printer = printer;
-                       }
-                       else 
-                               SAFE_FREE(printer);
-       
-
-                       break;
-               default:
-                       result=WERR_UNKNOWN_LEVEL;
-                       break;
-       }
-       
-       DEBUG(10,("get_a_printer: [%s] level %u returning %s\n", sharename, (unsigned int)level, dos_errstr(result)));
-
-       return result;
-}
-
-/****************************************************************************
- Deletes a NT_PRINTER_INFO_LEVEL struct.
-****************************************************************************/
-
-uint32 free_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level)
-{
-       uint32 result;
-       NT_PRINTER_INFO_LEVEL *printer = *pp_printer;
-
-       DEBUG(104,("freeing a printer at level [%d]\n", level));
-
-       if (printer == NULL)
-               return 0;
-       
-       switch (level) {
-               case 2:
-                       if (printer->info_2 != NULL) {
-                               free_nt_printer_info_level_2(&printer->info_2);
-                               result=0;
-                       } else
-                               result=4;
-                       break;
-
-               default:
-                       result=1;
-                       break;
-       }
-
-       SAFE_FREE(*pp_printer);
-       return result;
-}
-
-/****************************************************************************
-****************************************************************************/
-uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
-{
-       uint32 result;
-       DEBUG(104,("adding a printer at level [%d]\n", level));
-       dump_a_printer_driver(driver, level);
-       
-       switch (level) {
-               case 3:
-                       result=add_a_printer_driver_3(driver.info_3);
-                       break;
-
-               case 6:
-                       result=add_a_printer_driver_6(driver.info_6);
-                       break;
-
-               default:
-                       result=1;
-                       break;
-       }
-       
-       return result;
-}
-/****************************************************************************
-****************************************************************************/
-
-WERROR get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level,
-                            fstring drivername, const char *architecture, uint32 version)
-{
-       WERROR result;
-       
-       switch (level) {
-               case 3:
-                       /* Sometime we just want any version of the driver */
-                       
-                       if ( version == DRIVER_ANY_VERSION ) {
-                               /* look for Win2k first and then for NT4 */
-                               result = get_a_printer_driver_3(&driver->info_3, drivername, 
-                                               architecture, 3);
-                                               
-                               if ( !W_ERROR_IS_OK(result) ) {
-                                       result = get_a_printer_driver_3( &driver->info_3, 
-                                                       drivername, architecture, 2 );
-                               }
-                       } else {
-                               result = get_a_printer_driver_3(&driver->info_3, drivername, 
-                                       architecture, version);                         
-                       }
-                       break;
-                       
-               default:
-                       result=W_ERROR(1);
-                       break;
-       }
-       
-       if (W_ERROR_IS_OK(result))
-               dump_a_printer_driver(*driver, level);
-               
-       return result;
-}
-
-/****************************************************************************
-****************************************************************************/
-uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
-{
-       uint32 result;
-       
-       switch (level) {
-               case 3:
-               {
-                       NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
-                       if (driver.info_3 != NULL)
-                       {
-                               info3=driver.info_3;
-                               SAFE_FREE(info3->dependentfiles);
-                               ZERO_STRUCTP(info3);
-                               SAFE_FREE(info3);
-                               result=0;
-                       } else {
-                               result=4;
-                       }
-                       break;
-               }
-               case 6:
-               {
-                       NT_PRINTER_DRIVER_INFO_LEVEL_6 *info6;
-                       if (driver.info_6 != NULL) {
-                               info6=driver.info_6;
-                               SAFE_FREE(info6->dependentfiles);
-                               SAFE_FREE(info6->previousnames);
-                               ZERO_STRUCTP(info6);
-                               SAFE_FREE(info6);
-                               result=0;
-                       } else {
-                               result=4;
-                       }
-                       break;
-               }
-               default:
-                       result=1;
-                       break;
-       }
-       return result;
-}
-
-
-/****************************************************************************
-  Determine whether or not a particular driver is currently assigned
-  to a printer
-****************************************************************************/
-
-BOOL printer_driver_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3 )
-{
-       int snum;
-       int n_services = lp_numservices();
-       NT_PRINTER_INFO_LEVEL *printer = NULL;
-
-       if ( !info_3 ) 
-               return False;
-
-       DEBUG(5,("printer_driver_in_use: Beginning search through ntprinters.tdb...\n"));
-       
-       /* loop through the printers.tdb and check for the drivername */
-       
-       for (snum=0; snum<n_services; snum++) {
-               if ( !(lp_snum_ok(snum) && lp_print_ok(snum) ) )
-                       continue;
-               
-               if ( !W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_servicename(snum))) )
-                       continue;
-               
-               if ( !StrCaseCmp(info_3->name, printer->info_2->drivername) ) {
-                       free_a_printer( &printer, 2 );
-                       return True;
-               }
-               
-               free_a_printer( &printer, 2 );
-       }
-       
-       DEBUG(5,("printer_driver_in_use: Completed search through ntprinters.tdb...\n"));
-       
-       /* report that the driver is not in use by default */
-       
-       return False;
-}
-
-
-/**********************************************************************
- Check to see if a ogiven file is in use by *info
- *********************************************************************/
-static BOOL drv_file_in_use( char* file, NT_PRINTER_DRIVER_INFO_LEVEL_3 *info )
-{
-       int i = 0;
-       
-       if ( !info )
-               return False;
-               
-       if ( strequal(file, info->driverpath) )
-               return True;
-
-       if ( strequal(file, info->datafile) )
-               return True;
-
-       if ( strequal(file, info->configfile) )
-               return True;
-
-       if ( strequal(file, info->helpfile) )
-               return True;
-       
-       /* see of there are any dependent files to examine */
-       
-       if ( !info->dependentfiles )
-               return False;
-       
-       while ( *info->dependentfiles[i] ) {
-               if ( strequal(file, info->dependentfiles[i]) )
-                       return True;
-               i++;
-       }
-       
-       return False;
-
-}
-
-/**********************************************************************
- Utility function to remove the dependent file pointed to by the 
- input parameter from the list 
- *********************************************************************/
-
-static void trim_dependent_file( fstring files[], int idx )
-{
-       
-       /* bump everything down a slot */
-
-       while( *files[idx+1] ) {
-               fstrcpy( files[idx], files[idx+1] );
-               idx++;
-       }
-       
-       *files[idx] = '\0';
-
-       return; 
-}
-
-/**********************************************************************
- Check if any of the files used by src are also used by drv 
- *********************************************************************/
-
-static BOOL trim_overlap_drv_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *src, 
-                                      NT_PRINTER_DRIVER_INFO_LEVEL_3 *drv )
-{
-       BOOL    in_use = False;
-       int     i = 0;
-       
-       if ( !src || !drv )
-               return False;
-               
-       /* check each file.  Remove it from the src structure if it overlaps */
-       
-       if ( drv_file_in_use(src->driverpath, drv) ) {
-               in_use = True;
-               DEBUG(10,("Removing driverfile [%s] from list\n", src->driverpath));
-               fstrcpy( src->driverpath, "" );
-       }
-               
-       if ( drv_file_in_use(src->datafile, drv) ) {
-               in_use = True;
-               DEBUG(10,("Removing datafile [%s] from list\n", src->datafile));
-               fstrcpy( src->datafile, "" );
-       }
-               
-       if ( drv_file_in_use(src->configfile, drv) ) {
-               in_use = True;
-               DEBUG(10,("Removing configfile [%s] from list\n", src->configfile));
-               fstrcpy( src->configfile, "" );
-       }
-               
-       if ( drv_file_in_use(src->helpfile, drv) ) {
-               in_use = True;
-               DEBUG(10,("Removing helpfile [%s] from list\n", src->helpfile));
-               fstrcpy( src->helpfile, "" );
-       }
-       
-       /* are there any dependentfiles to examine? */
-       
-       if ( !src->dependentfiles )
-               return in_use;
-               
-       while ( *src->dependentfiles[i] ) {
-               if ( drv_file_in_use(src->dependentfiles[i], drv) ) {
-                       in_use = True;
-                       DEBUG(10,("Removing [%s] from dependent file list\n", src->dependentfiles[i]));
-                       trim_dependent_file( src->dependentfiles, i );
-               } else
-                       i++;
-       }               
-               
-       return in_use;
-}
-
-/****************************************************************************
-  Determine whether or not a particular driver files are currently being 
-  used by any other driver.  
-  
-  Return value is True if any files were in use by other drivers
-  and False otherwise.
-  
-  Upon return, *info has been modified to only contain the driver files
-  which are not in use
-****************************************************************************/
-
-BOOL printer_driver_files_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info )
-{
-       int                             i;
-       int                             ndrivers;
-       uint32                          version;
-       fstring                         *list = NULL;
-       NT_PRINTER_DRIVER_INFO_LEVEL    driver;
-       
-       if ( !info )
-               return False;
-       
-       version = info->cversion;
-       
-       /* loop over all driver versions */
-       
-       DEBUG(5,("printer_driver_files_in_use: Beginning search through ntdrivers.tdb...\n"));
-       
-       /* get the list of drivers */
-               
-       list = NULL;
-       ndrivers = get_ntdrivers(&list, info->environment, version);
-               
-       DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", 
-               ndrivers, info->environment, version));
-
-       /* check each driver for overlap in files */
-               
-       for (i=0; i<ndrivers; i++) {
-               DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
-                       
-               ZERO_STRUCT(driver);
-                       
-               if ( !W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, list[i], info->environment, version)) ) {
-                       SAFE_FREE(list);
-                       return True;
-               }
-                       
-               /* check if d2 uses any files from d1 */
-               /* only if this is a different driver than the one being deleted */
-                       
-               if ( !strequal(info->name, driver.info_3->name) ) {
-                       if ( trim_overlap_drv_files(info, driver.info_3) ) {
-                               free_a_printer_driver(driver, 3);
-                               SAFE_FREE( list );
-                               return True;
-                       }
-               }
-       
-               free_a_printer_driver(driver, 3);
-       }       
-       
-       SAFE_FREE(list);
-       
-       DEBUG(5,("printer_driver_files_in_use: Completed search through ntdrivers.tdb...\n"));
-       
-       driver.info_3 = info;
-       
-       if ( DEBUGLEVEL >= 20 )
-               dump_a_printer_driver( driver, 3 );
-       
-       return False;
-}
-
-/****************************************************************************
-  Actually delete the driver files.  Make sure that 
-  printer_driver_files_in_use() return False before calling 
-  this.
-****************************************************************************/
-
-static BOOL delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct current_user *user )
-{
-       int i = 0;
-       char *s;
-       struct tcon_context *conn;
-       DATA_BLOB null_pw;
-       NTSTATUS nt_status;
-       
-       if ( !info_3 )
-               return False;
-               
-       DEBUG(6,("delete_driver_files: deleting driver [%s] - version [%d]\n", info_3->name, info_3->cversion));
-       
-       /*
-        * Connect to the print$ share under the same account as the 
-        * user connected to the rpc pipe. Note we must be root to 
-        * do this.
-        */
-        
-       become_root();
-       null_pw = data_blob( NULL, 0 );
-        conn = make_connection_with_chdir( "print$", null_pw, "A:", user->vuid, &nt_status );
-       unbecome_root();
-       
-       if ( !conn ) {
-               DEBUG(0,("delete_driver_files: Unable to connect\n"));
-               return False;
-       }
-
-        /* Save who we are - we are temporarily becoming the connection user. */
-
-       if ( !become_user(conn, conn->vuid) ) {
-               DEBUG(0,("delete_driver_files: Can't become user!\n"));
-               return False;
-       }
-
-       /* now delete the files; must strip the '\print$' string from 
-          fron of path                                                */
-       
-       if ( *info_3->driverpath ) {
-               if ( (s = strchr( &info_3->driverpath[1], '\\' )) != NULL ) {
-                       DEBUG(10,("deleting driverfile [%s]\n", s));
-                       unlink_internals(conn, 0, s);
-               }
-       }
-               
-       if ( *info_3->configfile ) {
-               if ( (s = strchr( &info_3->configfile[1], '\\' )) != NULL ) {
-                       DEBUG(10,("deleting configfile [%s]\n", s));
-                       unlink_internals(conn, 0, s);
-               }
-       }
-       
-       if ( *info_3->datafile ) {
-               if ( (s = strchr( &info_3->datafile[1], '\\' )) != NULL ) {
-                       DEBUG(10,("deleting datafile [%s]\n", s));
-                       unlink_internals(conn, 0, s);
-               }
-       }
-       
-       if ( *info_3->helpfile ) {
-               if ( (s = strchr( &info_3->helpfile[1], '\\' )) != NULL ) {
-                       DEBUG(10,("deleting helpfile [%s]\n", s));
-                       unlink_internals(conn, 0, s);
-               }
-       }
-       
-       /* check if we are done removing files */
-       
-       if ( info_3->dependentfiles ) {
-               while ( *info_3->dependentfiles[i] ) {
-                       char *file;
-
-                       /* bypass the "\print$" portion of the path */
-                       
-                       if ( (file = strchr( info_3->dependentfiles[i]+1, '\\' )) != NULL ) {
-                               DEBUG(10,("deleting dependent file [%s]\n", file));
-                               unlink_internals(conn, 0, file );
-                       }
-                       
-                       i++;
-               }
-       }
-
-       unbecome_user();
-       
-       return True;
-}
-
-/****************************************************************************
- Remove a printer driver from the TDB.  This assumes that the the driver was
- previously looked up.
- ***************************************************************************/
-
-WERROR delete_printer_driver( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct current_user *user,
-                              uint32 version, BOOL delete_files )
-{
-       pstring         key;
-       fstring         arch;
-       TDB_DATA        kbuf, dbuf;
-       NT_PRINTER_DRIVER_INFO_LEVEL    ctr;
-
-       /* delete the tdb data first */
-
-       get_short_archi(arch, info_3->environment);
-       slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX,
-               arch, version, info_3->name);
-
-       DEBUG(5,("delete_printer_driver: key = [%s] delete_files = %s\n",
-               key, delete_files ? "TRUE" : "FALSE" ));
-
-       ctr.info_3 = info_3;
-       dump_a_printer_driver( ctr, 3 );
-
-       kbuf.dptr=key;
-       kbuf.dsize=strlen(key)+1;
-
-       /* check if the driver actually exists for this environment */
-       
-       dbuf = tdb_fetch( tdb_drivers, kbuf );
-       if ( !dbuf.dptr ) {
-               DEBUG(8,("delete_printer_driver: Driver unknown [%s]\n", key));
-               return WERR_UNKNOWN_PRINTER_DRIVER;
-       }
-               
-       SAFE_FREE( dbuf.dptr );
-       
-       /* ok... the driver exists so the delete should return success */
-               
-       if (tdb_delete(tdb_drivers, kbuf) == -1) {
-               DEBUG (0,("delete_printer_driver: fail to delete %s!\n", key));
-               return WERR_ACCESS_DENIED;
-       }
-
-       /*
-        * now delete any associated files if delete_files == True
-        * even if this part failes, we return succes because the
-        * driver doesn not exist any more
-        */
-
-       if ( delete_files )
-               delete_driver_files( info_3, user );
-                       
-               
-       DEBUG(5,("delete_printer_driver: driver delete successful [%s]\n", key));
-
-       return WERR_OK;
-       }
-       
-/****************************************************************************
- Store a security desc for a printer.
-****************************************************************************/
-
-WERROR nt_printing_setsec(const char *printername, SEC_DESC_BUF *secdesc_ctr)
-{
-       SEC_DESC_BUF *new_secdesc_ctr = NULL;
-       SEC_DESC_BUF *old_secdesc_ctr = NULL;
-       prs_struct ps;
-       TALLOC_CTX *mem_ctx = NULL;
-       fstring key;
-       WERROR status;
-
-       mem_ctx = talloc_init("nt_printing_setsec");
-       if (mem_ctx == NULL)
-               return WERR_NOMEM;
-
-        /* The old owner and group sids of the security descriptor are not
-          present when new ACEs are added or removed by changing printer
-          permissions through NT.  If they are NULL in the new security
-          descriptor then copy them over from the old one. */
-
-       if (!secdesc_ctr->sec->owner_sid || !secdesc_ctr->sec->grp_sid) {
-               DOM_SID *owner_sid, *group_sid;
-               SEC_ACL *dacl, *sacl;
-               SEC_DESC *psd = NULL;
-               size_t size;
-
-               nt_printing_getsec(mem_ctx, printername, &old_secdesc_ctr);
-
-               /* Pick out correct owner and group sids */
-
-               owner_sid = secdesc_ctr->sec->owner_sid ?
-                       secdesc_ctr->sec->owner_sid :
-                       old_secdesc_ctr->sec->owner_sid;
-
-               group_sid = secdesc_ctr->sec->grp_sid ?
-                       secdesc_ctr->sec->grp_sid :
-                       old_secdesc_ctr->sec->grp_sid;
-
-               dacl = secdesc_ctr->sec->dacl ?
-                       secdesc_ctr->sec->dacl :
-                       old_secdesc_ctr->sec->dacl;
-
-               sacl = secdesc_ctr->sec->sacl ?
-                       secdesc_ctr->sec->sacl :
-                       old_secdesc_ctr->sec->sacl;
-
-               /* Make a deep copy of the security descriptor */
-
-               psd = make_sec_desc(mem_ctx, secdesc_ctr->sec->revision,
-                                   owner_sid, group_sid,
-                                   sacl,
-                                   dacl,
-                                   &size);
-
-               new_secdesc_ctr = make_sec_desc_buf(mem_ctx, size, psd);
-       }
-
-       if (!new_secdesc_ctr) {
-               new_secdesc_ctr = secdesc_ctr;
-       }
-
-       /* Store the security descriptor in a tdb */
-
-       prs_init(&ps, (uint32)sec_desc_size(new_secdesc_ctr->sec) +
-                sizeof(SEC_DESC_BUF), mem_ctx, MARSHALL);
-
-       if (!sec_io_desc_buf("nt_printing_setsec", &new_secdesc_ctr,
-                            &ps, 1)) {
-               status = WERR_BADFUNC;
-               goto out;
-       }
-
-       slprintf(key, sizeof(key)-1, "SECDESC/%s", printername);
-
-       if (tdb_prs_store(tdb_printers, key, &ps)==0) {
-               status = WERR_OK;
-       } else {
-               DEBUG(1,("Failed to store secdesc for %s\n", printername));
-               status = WERR_BADFUNC;
-       }
-
-       /* Free malloc'ed memory */
-
- out:
-
-       prs_mem_free(&ps);
-       if (mem_ctx)
-               talloc_destroy(mem_ctx);
-       return status;
-}
-
-/****************************************************************************
- Construct a default security descriptor buffer for a printer.
-****************************************************************************/
-
-static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx)
-{
-       SEC_ACE ace[3];
-       SEC_ACCESS sa;
-       SEC_ACL *psa = NULL;
-       SEC_DESC_BUF *sdb = NULL;
-       SEC_DESC *psd = NULL;
-       DOM_SID owner_sid;
-       size_t sd_size;
-
-       /* Create an ACE where Everyone is allowed to print */
-
-       init_sec_access(&sa, PRINTER_ACE_PRINT);
-       init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
-                    sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
-
-       /* Make the security descriptor owned by the Administrators group
-          on the PDC of the domain. */
-
-       if (secrets_fetch_domain_sid(lp_workgroup(), &owner_sid)) {
-               sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
-       } else {
-
-               /* Backup plan - make printer owned by admins.
-                  This should emulate a lanman printer as security
-                  settings can't be changed. */
-
-               sid_copy(&owner_sid, get_global_sam_sid());
-               sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
-       }
-
-       init_sec_access(&sa, PRINTER_ACE_FULL_CONTROL);
-       init_sec_ace(&ace[1], &owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
-                    sa, SEC_ACE_FLAG_OBJECT_INHERIT |
-                    SEC_ACE_FLAG_INHERIT_ONLY);
-
-       init_sec_access(&sa, PRINTER_ACE_FULL_CONTROL);
-       init_sec_ace(&ace[2], &owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
-                    sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
-
-       /* The ACL revision number in rpc_secdesc.h differs from the one
-          created by NT when setting ACE entries in printer
-          descriptors.  NT4 complains about the property being edited by a
-          NT5 machine. */
-
-       if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) != NULL) {
-               psd = make_sec_desc(ctx, SEC_DESC_REVISION,
-                                   &owner_sid, NULL,
-                                   NULL, psa, &sd_size);
-       }
-
-       if (!psd) {
-               DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n"));
-               return NULL;
-       }
-
-       sdb = make_sec_desc_buf(ctx, sd_size, psd);
-
-       DEBUG(4,("construct_default_printer_sdb: size = %u.\n",
-                (unsigned int)sd_size));
-
-       return sdb;
-}
-
-/****************************************************************************
- Get a security desc for a printer.
-****************************************************************************/
-
-BOOL nt_printing_getsec(TALLOC_CTX *ctx, const char *printername, SEC_DESC_BUF **secdesc_ctr)
-{
-       prs_struct ps;
-       fstring key;
-       char *temp;
-
-       if (strlen(printername) > 2 && (temp = strchr(printername + 2, '\\'))) {
-               printername = temp + 1;
-       }
-
-       /* Fetch security descriptor from tdb */
-
-       slprintf(key, sizeof(key)-1, "SECDESC/%s", printername);
-
-       if (tdb_prs_fetch(tdb_printers, key, &ps, ctx)!=0 ||
-           !sec_io_desc_buf("nt_printing_getsec", secdesc_ctr, &ps, 1)) {
-
-               DEBUG(4,("using default secdesc for %s\n", printername));
-
-               if (!(*secdesc_ctr = construct_default_printer_sdb(ctx))) {
-                       return False;
-               }
-
-               /* Save default security descriptor for later */
-
-               prs_init(&ps, (uint32)sec_desc_size((*secdesc_ctr)->sec) +
-                               sizeof(SEC_DESC_BUF), ctx, MARSHALL);
-
-               if (sec_io_desc_buf("nt_printing_getsec", secdesc_ctr, &ps, 1))
-                       tdb_prs_store(tdb_printers, key, &ps);
-
-               prs_mem_free(&ps);
-
-               return True;
-       }
-
-       /* If security descriptor is owned by S-1-1-0 and winbindd is up,
-          this security descriptor has been created when winbindd was
-          down.  Take ownership of security descriptor. */
-
-       if (sid_equal((*secdesc_ctr)->sec->owner_sid, &global_sid_World)) {
-               DOM_SID owner_sid;
-
-               /* Change sd owner to workgroup administrator */
-
-               if (secrets_fetch_domain_sid(lp_workgroup(), &owner_sid)) {
-                       SEC_DESC_BUF *new_secdesc_ctr = NULL;
-                       SEC_DESC *psd = NULL;
-                       size_t size;
-
-                       /* Create new sd */
-
-                       sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
-
-                       psd = make_sec_desc(ctx, (*secdesc_ctr)->sec->revision,
-                                           &owner_sid,
-                                           (*secdesc_ctr)->sec->grp_sid,
-                                           (*secdesc_ctr)->sec->sacl,
-                                           (*secdesc_ctr)->sec->dacl,
-                                           &size);
-
-                       new_secdesc_ctr = make_sec_desc_buf(ctx, size, psd);
-
-                       /* Swap with other one */
-
-                       *secdesc_ctr = new_secdesc_ctr;
-
-                       /* Set it */
-
-                       nt_printing_setsec(printername, *secdesc_ctr);
-               }
-       }
-
-       if (DEBUGLEVEL >= 10) {
-               SEC_ACL *the_acl = (*secdesc_ctr)->sec->dacl;
-               int i;
-
-               DEBUG(10, ("secdesc_ctr for %s has %d aces:\n", 
-                          printername, the_acl->num_aces));
-
-               for (i = 0; i < the_acl->num_aces; i++) {
-                       fstring sid_str;
-
-                       sid_to_string(sid_str, &the_acl->ace[i].trustee);
-
-                       DEBUG(10, ("%s %d %d 0x%08x\n", sid_str,
-                                  the_acl->ace[i].type, the_acl->ace[i].flags, 
-                                  the_acl->ace[i].info.mask)); 
-               }
-       }
-
-       prs_mem_free(&ps);
-       return True;
-}
-
-/* error code:
-       0: everything OK
-       1: level not implemented
-       2: file doesn't exist
-       3: can't allocate memory
-       4: can't free memory
-       5: non existant struct
-*/
-
-/*
-       A printer and a printer driver are 2 different things.
-       NT manages them separatelly, Samba does the same.
-       Why ? Simply because it's easier and it makes sense !
-       
-       Now explanation: You have 3 printers behind your samba server,
-       2 of them are the same make and model (laser A and B). But laser B
-       has an 3000 sheet feeder and laser A doesn't such an option.
-       Your third printer is an old dot-matrix model for the accounting :-).
-       
-       If the /usr/local/samba/lib directory (default dir), you will have
-       5 files to describe all of this.
-       
-       3 files for the printers (1 by printer):
-               NTprinter_laser A
-               NTprinter_laser B
-               NTprinter_accounting
-       2 files for the drivers (1 for the laser and 1 for the dot matrix)
-               NTdriver_printer model X
-               NTdriver_printer model Y
-
-jfm: I should use this comment for the text file to explain
-       same thing for the forms BTW.
-       Je devrais mettre mes commentaires en francais, ca serait mieux :-)
-
-*/
-
-/* Convert generic access rights to printer object specific access rights.
-   It turns out that NT4 security descriptors use generic access rights and
-   NT5 the object specific ones. */
-
-void map_printer_permissions(SEC_DESC *sd)
-{
-       int i;
-
-       for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) {
-               se_map_generic(&sd->dacl->ace[i].info.mask,
-                              &printer_generic_mapping);
-       }
-}
-
-/****************************************************************************
- Check a user has permissions to perform the given operation.  We use the
- permission constants defined in include/rpc_spoolss.h to check the various
- actions we perform when checking printer access.
-
-   PRINTER_ACCESS_ADMINISTER:
-       print_queue_pause, print_queue_resume, update_printer_sec,
-       update_printer, spoolss_addprinterex_level_2,
-       _spoolss_setprinterdata
-
-   PRINTER_ACCESS_USE:
-       print_job_start
-
-   JOB_ACCESS_ADMINISTER:
-       print_job_delete, print_job_pause, print_job_resume,
-       print_queue_purge
-
- ****************************************************************************/
-BOOL print_access_check(struct current_user *user, int snum, int access_type)
-{
-       SEC_DESC_BUF *secdesc = NULL;
-       uint32 access_granted;
-       NTSTATUS status;
-       BOOL result;
-       const char *pname;
-       TALLOC_CTX *mem_ctx = NULL;
-       extern struct current_user current_user;
-       
-       /* If user is NULL then use the current_user structure */
-
-       if (!user)
-               user = &current_user;
-
-       /* Always allow root or printer admins to do anything */
-
-       if (user->uid == 0 ||
-           user_in_list(uidtoname(user->uid), lp_printer_admin(snum), user->groups, user->ngroups)) {
-               return True;
-       }
-
-       /* Get printer name */
-
-       pname = PRINTERNAME(snum);
-
-       if (!pname || !*pname) {
-               errno = EACCES;
-               return False;
-       }
-
-       /* Get printer security descriptor */
-
-       if(!(mem_ctx = talloc_init("print_access_check"))) {
-               errno = ENOMEM;
-               return False;
-       }
-
-       nt_printing_getsec(mem_ctx, pname, &secdesc);
-
-       if (access_type == JOB_ACCESS_ADMINISTER) {
-               SEC_DESC_BUF *parent_secdesc = secdesc;
-
-               /* Create a child security descriptor to check permissions
-                  against.  This is because print jobs are child objects
-                  objects of a printer. */
-
-               secdesc = se_create_child_secdesc(mem_ctx, parent_secdesc->sec, False);
-
-               /* Now this is the bit that really confuses me.  The access
-                  type needs to be changed from JOB_ACCESS_ADMINISTER to
-                  PRINTER_ACCESS_ADMINISTER for this to work.  Something
-                  to do with the child (job) object becoming like a
-                  printer??  -tpot */
-
-               access_type = PRINTER_ACCESS_ADMINISTER;
-       }
-       
-       /* Check access */
-       
-       map_printer_permissions(secdesc->sec);
-
-       result = se_access_check(secdesc->sec, user->nt_user_token, access_type,
-                                &access_granted, &status);
-
-       DEBUG(4, ("access check was %s\n", result ? "SUCCESS" : "FAILURE"));
-
-       talloc_destroy(mem_ctx);
-       
-       if (!result)
-               errno = EACCES;
-
-       return result;
-}
-
-/****************************************************************************
- Check the time parameters allow a print operation.
-*****************************************************************************/
-
-BOOL print_time_access_check(int snum)
-{
-       NT_PRINTER_INFO_LEVEL *printer = NULL;
-       BOOL ok = False;
-       time_t now = time(NULL);
-       struct tm *t;
-       uint32 mins;
-
-       if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_servicename(snum))))
-               return False;
-
-       if (printer->info_2->starttime == 0 && printer->info_2->untiltime == 0)
-               ok = True;
-
-       t = gmtime(&now);
-       mins = (uint32)t->tm_hour*60 + (uint32)t->tm_min;
-
-       if (mins >= printer->info_2->starttime && mins <= printer->info_2->untiltime)
-               ok = True;
-
-       free_a_printer(&printer, 2);
-
-       if (!ok)
-               errno = EACCES;
-
-       return ok;
-}
-
diff --git a/source4/registry/reg_printing.c b/source4/registry/reg_printing.c
deleted file mode 100644 (file)
index 619ffc7..0000000
+++ /dev/null
@@ -1,829 +0,0 @@
-/* 
- *  Unix SMB/CIFS implementation.
- *  RPC Pipe client / server routines
- *  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
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *  
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *  
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/* Implementation of registry virtual views for printing information */
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_SRV
-
-#define MAX_TOP_LEVEL_KEYS     3
-
-/* some symbolic indexes into the top_level_keys */
-
-#define KEY_INDEX_ENVIR                0
-#define KEY_INDEX_FORMS                1
-#define KEY_INDEX_PRINTER      2
-
-static char *top_level_keys[MAX_TOP_LEVEL_KEYS] = { 
-       "Environments", 
-       "Forms",
-       "Printers" 
-};
-
-
-/**********************************************************************
- It is safe to assume that every registry path passed into on of 
- the exported functions here begins with KEY_PRINTING else
- these functions would have never been called.  This is a small utility
- function to strip the beginning of the path and make a copy that the 
- caller can modify.  Note that the caller is responsible for releasing
- the memory allocated here.
- **********************************************************************/
-
-static char* trim_reg_path( char *path )
-{
-       char *p;
-       uint16 key_len = strlen(KEY_PRINTING);
-       
-       /* 
-        * sanity check...this really should never be True.
-        * It is only here to prevent us from accessing outside
-        * the path buffer in the extreme case.
-        */
-       
-       if ( strlen(path) < key_len ) {
-               DEBUG(0,("trim_reg_path: Registry path too short! [%s]\n", path));
-               DEBUG(0,("trim_reg_path: KEY_PRINTING => [%s]!\n", KEY_PRINTING));
-               return NULL;
-       }
-       
-       
-       p = path + strlen( KEY_PRINTING );
-       
-       if ( *p == '\\' )
-               p++;
-       
-       if ( *p )
-               return strdup(p);
-       else
-               return NULL;
-}
-
-/**********************************************************************
- handle enumeration of subkeys below KEY_PRINTING\Environments
- *********************************************************************/
-static int print_subpath_environments( char *key, REGSUBKEY_CTR *subkeys )
-{
-       const char *environments[] = {
-               "Windows 4.0",
-               "Windows NT x86",
-               "Windows NT R4000",
-               "Windows NT Alpha_AXP",
-               "Windows NT PowerPC",
-               NULL };
-       fstring *drivers = NULL;
-       int i, env_index, num_drivers;
-       BOOL valid_env = False;
-       char *base, *new_path;
-       char *keystr;
-       char *key2 = NULL;
-       int num_subkeys = -1;
-
-       DEBUG(10,("print_subpath_environments: key=>[%s]\n", key ? key : "NULL" ));
-       
-       /* listed architectures of installed drivers */
-       
-       if ( !key ) 
-       {
-               /* Windows 9x drivers */
-               
-               if ( get_ntdrivers( &drivers, environments[0], 0 ) )
-                       regsubkey_ctr_addkey( subkeys,  environments[0] );
-               SAFE_FREE( drivers );
-                                       
-               /* Windows NT/2k intel drivers */
-               
-               if ( get_ntdrivers( &drivers, environments[1], 2 ) 
-                       || get_ntdrivers( &drivers, environments[1], 3 ) )
-               {
-                       regsubkey_ctr_addkey( subkeys,  environments[1] );
-               }
-               SAFE_FREE( drivers );
-               
-               /* Windows NT 4.0; non-intel drivers */
-               for ( i=2; environments[i]; i++ ) {
-                       if ( get_ntdrivers( &drivers, environments[i], 2 ) )
-                               regsubkey_ctr_addkey( subkeys,  environments[i] );
-               
-               }
-               SAFE_FREE( drivers );
-
-               num_subkeys = regsubkey_ctr_numkeys( subkeys ); 
-               goto done;
-       }
-       
-       /* we are dealing with a subkey of "Environments */
-       
-       key2 = strdup( key );
-       keystr = key2;
-       reg_split_path( keystr, &base, &new_path );
-       
-       /* sanity check */
-       
-       for ( env_index=0; environments[env_index]; env_index++ ) {
-               if ( StrCaseCmp( environments[env_index], base ) == 0 ) {
-                       valid_env = True;
-                       break;
-               }
-       }
-               
-       if ( !valid_env )
-               return -1;
-
-       /* enumerate driver versions; environment is environments[env_index] */
-       
-       if ( !new_path ) {
-               switch ( env_index ) {
-                       case 0: /* Win9x */
-                               if ( get_ntdrivers( &drivers, environments[0], 0 ) ) {
-                                       regsubkey_ctr_addkey( subkeys, "0" );
-                                       SAFE_FREE( drivers );
-                               }
-                               break;
-                       case 1: /* Windows NT/2k - intel */
-                               if ( get_ntdrivers( &drivers, environments[1], 2 ) ) {
-                                       regsubkey_ctr_addkey( subkeys, "2" );
-                                       SAFE_FREE( drivers );
-                               }
-                               if ( get_ntdrivers( &drivers, environments[1], 3 ) ) {
-                                       regsubkey_ctr_addkey( subkeys, "3" );
-                                       SAFE_FREE( drivers );
-                               }
-                               break;
-                       default: /* Windows NT - nonintel */
-                               if ( get_ntdrivers( &drivers, environments[env_index], 2 ) ) {
-                                       regsubkey_ctr_addkey( subkeys, "2" );
-                                       SAFE_FREE( drivers );
-                               }
-                       
-               }
-               
-               num_subkeys = regsubkey_ctr_numkeys( subkeys ); 
-               goto done;
-       }
-       
-       /* we finally get to enumerate the drivers */
-       
-       keystr = new_path;
-       reg_split_path( keystr, &base, &new_path );
-       
-       if ( !new_path ) {
-               num_drivers = get_ntdrivers( &drivers, environments[env_index], atoi(base) );
-               for ( i=0; i<num_drivers; i++ )
-                       regsubkey_ctr_addkey( subkeys, drivers[i] );
-                       
-               num_subkeys = regsubkey_ctr_numkeys( subkeys ); 
-               goto done;
-       }
-       
-done:
-       SAFE_FREE( key2 );
-               
-       return num_subkeys;
-}
-
-/***********************************************************************
- simple function to prune a pathname down to the basename of a file 
- **********************************************************************/
-static char* dos_basename ( char *path )
-{
-       char *p;
-       
-       p = strrchr( path, '\\' );
-       if ( p )
-               p++;
-       else
-               p = path;
-               
-       return p;
-}
-
-/**********************************************************************
- handle enumeration of values below 
- KEY_PRINTING\Environments\<arch>\<version>\<drivername>
- *********************************************************************/
-static int print_subpath_values_environments( char *key, REGVAL_CTR *val )
-{
-       char            *keystr;
-       char            *key2 = NULL;
-       char            *base, *new_path;
-       fstring         env;
-       fstring         driver;
-       int             version;
-       NT_PRINTER_DRIVER_INFO_LEVEL    driver_ctr;
-       NT_PRINTER_DRIVER_INFO_LEVEL_3  *info3;
-       WERROR          w_result;
-       char            *buffer = NULL;
-       char            *buffer2 = NULL;
-       int             buffer_size = 0;
-       int             i, length;
-       char            *filename;
-       UNISTR2         data;;
-       
-       DEBUG(8,("print_subpath_values_environments: Enter key => [%s]\n", key ? key : "NULL"));
-       
-       if ( !key )
-               return 0;
-               
-       /* 
-        * The only key below KEY_PRINTING\Environments that 
-        * posseses values is each specific printer driver 
-        * First get the arch, version, & driver name
-        */
-       
-       /* env */
-       
-       key2 = strdup( key );
-       keystr = key2;
-       reg_split_path( keystr, &base, &new_path );
-       if ( !base || !new_path )
-               return 0;
-       fstrcpy( env, base );
-       
-       /* version */
-       
-       keystr = new_path;
-       reg_split_path( keystr, &base, &new_path );
-       if ( !base || !new_path )
-               return 0;
-       version = atoi( base );
-
-       /* printer driver name */
-       
-       keystr = new_path;
-       reg_split_path( keystr, &base, &new_path );
-       /* new_path should be NULL here since this must be the last key */
-       if ( !base || new_path )
-               return 0;
-       fstrcpy( driver, base );
-
-       w_result = get_a_printer_driver( &driver_ctr, 3, driver, env, version );
-
-       if ( !W_ERROR_IS_OK(w_result) )
-               return -1;
-               
-       /* build the values out of the driver information */
-       info3 = driver_ctr.info_3;
-       
-       filename = dos_basename( info3->driverpath );
-       init_unistr2( &data, filename, strlen(filename)+1 ); 
-       regval_ctr_addvalue( val, "Driver",             REG_SZ,       (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
-       
-       filename = dos_basename( info3->configfile );
-       init_unistr2( &data, filename, strlen(filename)+1 );
-       regval_ctr_addvalue( val, "Configuration File", REG_SZ,       (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
-       
-       filename = dos_basename( info3->datafile );
-       init_unistr2( &data, filename, strlen(filename)+1 );
-       regval_ctr_addvalue( val, "Data File",          REG_SZ,       (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
-       
-       filename = dos_basename( info3->helpfile );
-       init_unistr2( &data, filename, strlen(filename)+1 );
-       regval_ctr_addvalue( val, "Help File",          REG_SZ,       (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
-       
-       init_unistr2( &data, info3->defaultdatatype, strlen(info3->defaultdatatype)+1 );
-       regval_ctr_addvalue( val, "Data Type",          REG_SZ,       (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
-       
-       regval_ctr_addvalue( val, "Version",            REG_DWORD,    (char*)&info3->cversion, sizeof(info3->cversion) );
-       
-       if ( info3->dependentfiles )
-       {
-               /* place the list of dependent files in a single 
-                  character buffer, separating each file name by
-                  a NULL */
-                  
-               for ( i=0; strcmp(info3->dependentfiles[i], ""); i++ )
-               {
-                       /* strip the path to only the file's base name */
-               
-                       filename = dos_basename( info3->dependentfiles[i] );
-                       
-                       length = strlen(filename);
-               
-                       buffer2 = Realloc( buffer, buffer_size + (length + 1)*sizeof(uint16) );
-                       if ( !buffer2 )
-                               break;
-                       buffer = buffer2;
-                       
-                       init_unistr2( &data, filename, length+1 );
-                       memcpy( buffer+buffer_size, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
-               
-                       buffer_size += (length + 1)*sizeof(uint16);
-               }
-               
-               /* terminated by double NULL.  Add the final one here */
-               
-               buffer2 = Realloc( buffer, buffer_size + 2 );
-               if ( !buffer2 ) {
-                       SAFE_FREE( buffer );
-                       buffer_size = 0;
-               }
-               else {
-                       buffer = buffer2;
-                       buffer[buffer_size++] = '\0';
-                       buffer[buffer_size++] = '\0';
-               }
-       }
-       
-       regval_ctr_addvalue( val, "Dependent Files",    REG_MULTI_SZ, buffer, buffer_size );
-       
-       free_a_printer_driver( driver_ctr, 3 );
-       
-       SAFE_FREE( key2 );
-       SAFE_FREE( buffer );
-               
-       DEBUG(8,("print_subpath_values_environments: Exit\n"));
-       
-       return regval_ctr_numvals( val );
-}
-
-
-/**********************************************************************
- handle enumeration of subkeys below KEY_PRINTING\Forms
- Really just a stub function, but left here in case it needs to
- be expanded later on
- *********************************************************************/
-static int print_subpath_forms( char *key, REGSUBKEY_CTR *subkeys )
-{
-       DEBUG(10,("print_subpath_forms: key=>[%s]\n", key ? key : "NULL" ));
-       
-       /* there are no subkeys */
-       
-       if ( key )
-               return -1;
-       
-       return 0;
-}
-
-/**********************************************************************
- handle enumeration of values below KEY_PRINTING\Forms
- *********************************************************************/
-static int print_subpath_values_forms( char *key, REGVAL_CTR *val )
-{
-       int             num_values = 0;
-       uint32          data[8];
-       int             form_index = 1;
-       
-       DEBUG(10,("print_values_forms: key=>[%s]\n", key ? key : "NULL" ));
-       
-       /* handle ..\Forms\ */
-       
-       if ( !key )
-       {
-               nt_forms_struct *forms_list = NULL;
-               nt_forms_struct *form = NULL;
-               int i;
-               
-               if ( (num_values = get_ntforms( &forms_list )) == 0 ) 
-                       return 0;
-               
-               DEBUG(10,("print_subpath_values_forms: [%d] user defined forms returned\n",
-                       num_values));
-
-               /* handle user defined forms */
-                               
-               for ( i=0; i<num_values; i++ )
-               {
-                       form = &forms_list[i];
-                       
-                       data[0] = form->width;
-                       data[1] = form->length;
-                       data[2] = form->left;
-                       data[3] = form->top;
-                       data[4] = form->right;
-                       data[5] = form->bottom;
-                       data[6] = form_index++;
-                       data[7] = form->flag;
-                       
-                       regval_ctr_addvalue( val, form->name, REG_BINARY, (char*)data, sizeof(data) );
-               
-               }
-               
-               SAFE_FREE( forms_list );
-               forms_list = NULL;
-               
-               /* handle built-on forms */
-               
-               if ( (num_values = get_builtin_ntforms( &forms_list )) == 0 ) 
-                       return 0;
-               
-               DEBUG(10,("print_subpath_values_forms: [%d] built-in forms returned\n",
-                       num_values));
-                       
-               for ( i=0; i<num_values; i++ )
-               {
-                       form = &forms_list[i];
-                       
-                       data[0] = form->width;
-                       data[1] = form->length;
-                       data[2] = form->left;
-                       data[3] = form->top;
-                       data[4] = form->right;
-                       data[5] = form->bottom;
-                       data[6] = form_index++;
-                       data[7] = form->flag;
-                                       
-                       regval_ctr_addvalue( val, form->name, REG_BINARY, (char*)data, sizeof(data) );
-               }
-               
-               SAFE_FREE( forms_list );
-       }
-       
-       return num_values;
-}
-
-/**********************************************************************
- handle enumeration of subkeys below KEY_PRINTING\Printers
- *********************************************************************/
-static int print_subpath_printers( char *key, REGSUBKEY_CTR *subkeys )
-{
-       int n_services = lp_numservices();      
-       int snum;
-       fstring sname;
-       int i;
-       int num_subkeys = 0;
-       char *keystr, *key2 = NULL;
-       char *base, *new_path;
-       NT_PRINTER_INFO_LEVEL *printer = NULL;
-       fstring *subkey_names = NULL;
-       
-       DEBUG(10,("print_subpath_printers: key=>[%s]\n", key ? key : "NULL" ));
-       
-       if ( !key )
-       {
-               /* enumerate all printers */
-               
-               for (snum=0; snum<n_services; snum++) {
-                       if ( !(lp_snum_ok(snum) && lp_print_ok(snum) ) )
-                               continue;
-                               
-                       fstrcpy( sname, lp_servicename(snum) );
-                               
-                       regsubkey_ctr_addkey( subkeys, sname );
-               }
-               
-               num_subkeys = regsubkey_ctr_numkeys( subkeys );
-               goto done;
-       }
-
-       /* get information for a specific printer */
-       
-       key2 = strdup( key );
-       keystr = key2;
-       reg_split_path( keystr, &base, &new_path );
-
-               if ( !W_ERROR_IS_OK( get_a_printer(NULL, &printer, 2, base) ) )
-               goto done;
-
-       num_subkeys = get_printer_subkeys( &printer->info_2->data, new_path?new_path:"", &subkey_names );
-       
-       for ( i=0; i<num_subkeys; i++ )
-               regsubkey_ctr_addkey( subkeys, subkey_names[i] );
-       
-       free_a_printer( &printer, 2 );
-                       
-       /* no other subkeys below here */
-
-done:  
-       SAFE_FREE( key2 );
-       SAFE_FREE( subkey_names );
-       
-       return num_subkeys;
-}
-
-/**********************************************************************
- handle enumeration of values below KEY_PRINTING\Printers
- *********************************************************************/
-static int print_subpath_values_printers( char *key, REGVAL_CTR *val )
-{
-       int             num_values = 0;
-       char            *keystr, *key2 = NULL;
-       char            *base, *new_path;
-       NT_PRINTER_INFO_LEVEL   *printer = NULL;
-       NT_PRINTER_INFO_LEVEL_2 *info2;
-       DEVICEMODE      *devmode;
-       prs_struct      prs;
-       uint32          offset;
-       int             snum;
-       fstring         printername; 
-       NT_PRINTER_DATA *p_data;
-       int             i, key_index;
-       UNISTR2         data;
-       
-       /* 
-        * Theres are tw cases to deal with here
-        * (1) enumeration of printer_info_2 values
-        * (2) enumeration of the PrinterDriverData subney
-        */
-        
-       if ( !key ) {
-               /* top level key has no values */
-               goto done;
-       }
-       
-       key2 = strdup( key );
-       keystr = key2;
-       reg_split_path( keystr, &base, &new_path );
-       
-       fstrcpy( printername, base );
-       
-       if ( !new_path ) 
-       {
-               /* we are dealing with the printer itself */
-
-               if ( !W_ERROR_IS_OK( get_a_printer(NULL, &printer, 2, printername) ) )
-                       goto done;
-
-               info2 = printer->info_2;
-               
-
-               regval_ctr_addvalue( val, "Attributes",       REG_DWORD, (char*)&info2->attributes,       sizeof(info2->attributes) );
-               regval_ctr_addvalue( val, "Priority",         REG_DWORD, (char*)&info2->priority,         sizeof(info2->attributes) );
-               regval_ctr_addvalue( val, "ChangeID",         REG_DWORD, (char*)&info2->changeid,         sizeof(info2->changeid) );
-               regval_ctr_addvalue( val, "Default Priority", REG_DWORD, (char*)&info2->default_priority, sizeof(info2->default_priority) );
-               regval_ctr_addvalue( val, "Status",           REG_DWORD, (char*)&info2->status,           sizeof(info2->status) );
-               regval_ctr_addvalue( val, "StartTime",        REG_DWORD, (char*)&info2->starttime,        sizeof(info2->starttime) );
-               regval_ctr_addvalue( val, "UntilTime",        REG_DWORD, (char*)&info2->untiltime,        sizeof(info2->untiltime) );
-               regval_ctr_addvalue( val, "cjobs",            REG_DWORD, (char*)&info2->cjobs,            sizeof(info2->cjobs) );
-               regval_ctr_addvalue( val, "AveragePPM",       REG_DWORD, (char*)&info2->averageppm,       sizeof(info2->averageppm) );
-
-               init_unistr2( &data, info2->printername, strlen(info2->printername)+1 );
-               regval_ctr_addvalue( val, "Name",             REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
-               init_unistr2( &data, info2->location, strlen(info2->location)+1 );
-               regval_ctr_addvalue( val, "Location",         REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
-               init_unistr2( &data, info2->comment, strlen(info2->comment)+1 );
-               regval_ctr_addvalue( val, "Comment",          REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
-               init_unistr2( &data, info2->parameters, strlen(info2->parameters)+1 );
-               regval_ctr_addvalue( val, "Parameters",       REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
-               init_unistr2( &data, info2->portname, strlen(info2->portname)+1 );
-               regval_ctr_addvalue( val, "Port",             REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
-               init_unistr2( &data, info2->servername, strlen(info2->servername)+1 );
-               regval_ctr_addvalue( val, "Server",           REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
-               init_unistr2( &data, info2->sharename, strlen(info2->sharename)+1 );
-               regval_ctr_addvalue( val, "Share",            REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
-               init_unistr2( &data, info2->drivername, strlen(info2->drivername)+1 );
-               regval_ctr_addvalue( val, "Driver",           REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
-               init_unistr2( &data, info2->sepfile, strlen(info2->sepfile)+1 );
-               regval_ctr_addvalue( val, "Separator File",   REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
-               init_unistr2( &data, "winprint", strlen("winprint")+1 );
-               regval_ctr_addvalue( val, "Print Processor",  REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
-               
-               
-               /* use a prs_struct for converting the devmode and security 
-                  descriptor to REG_BIARY */
-               
-               prs_init( &prs, MAX_PDU_FRAG_LEN, regval_ctr_getctx(val), MARSHALL);
-
-               /* stream the device mode */
-               
-               snum = lp_servicenumber(info2->sharename);
-               if ( (devmode = construct_dev_mode( snum )) != NULL )
-               {                       
-                       if ( spoolss_io_devmode( "devmode", &prs, 0, devmode ) ) {
-                       
-                               offset = prs_offset( &prs );
-                               
-                               regval_ctr_addvalue( val, "Default Devmode", REG_BINARY, prs_data_p(&prs), offset );
-                       }
-                       
-                       
-               }
-               
-               prs_mem_clear( &prs );
-               prs_set_offset( &prs, 0 );
-               
-               if ( info2->secdesc_buf && info2->secdesc_buf->len ) 
-               {
-                       if ( sec_io_desc("sec_desc", &info2->secdesc_buf->sec, &prs, 0 ) ) {
-                       
-                               offset = prs_offset( &prs );
-                       
-                               regval_ctr_addvalue( val, "Security", REG_BINARY, prs_data_p(&prs), offset );
-                       }
-               }
-
-               prs_mem_free( &prs );
-               
-               num_values = regval_ctr_numvals( val ); 
-               
-               goto done;
-               
-       }
-               
-       /* now enumerate the key */
-       
-       if ( !W_ERROR_IS_OK( get_a_printer(NULL, &printer, 2, printername) ) )
-               goto done;
-       
-       /* iterate over all printer data and fill the regval container */
-       
-       p_data = &printer->info_2->data;
-       if ( (key_index = lookup_printerkey( p_data, new_path )) == -1  ) {
-               DEBUG(10,("print_subpath_values_printer: Unknown keyname [%s]\n", new_path));
-               goto done;
-       }
-       
-       num_values = regval_ctr_numvals( &p_data->keys[key_index].values );
-       
-       for ( i=0; i<num_values; i++ )
-               regval_ctr_copyvalue( val, regval_ctr_specific_value(&p_data->keys[key_index].values, i) );
-                       
-
-done:
-       if ( printer )
-               free_a_printer( &printer, 2 );
-               
-       SAFE_FREE( key2 ); 
-       
-       return num_values;
-}
-
-/**********************************************************************
- Routine to handle enumeration of subkeys and values 
- below KEY_PRINTING (depending on whether or not subkeys/val are 
- valid pointers. 
- *********************************************************************/
-static int handle_printing_subpath( char *key, REGSUBKEY_CTR *subkeys, REGVAL_CTR *val )
-{
-       int result = 0;
-       char *p, *base;
-       int i;
-       
-       DEBUG(10,("handle_printing_subpath: key=>[%s]\n", key ));
-       
-       /* 
-        * break off the first part of the path 
-        * topmost base **must** be one of the strings 
-        * in top_level_keys[]
-        */
-       
-       reg_split_path( key, &base, &p);
-               
-       for ( i=0; i<MAX_TOP_LEVEL_KEYS; i++ ) {
-               if ( StrCaseCmp( top_level_keys[i], base ) == 0 )
-                       break;
-       }
-       
-       DEBUG(10,("handle_printing_subpath: base=>[%s], i==[%d]\n", base, i));  
-               
-       if ( !(i < MAX_TOP_LEVEL_KEYS) )
-               return -1;
-                                               
-       /* Call routine to handle each top level key */
-       switch ( i )
-       {
-               case KEY_INDEX_ENVIR:
-                       if ( subkeys )
-                               print_subpath_environments( p, subkeys );
-                       if ( val )
-                               print_subpath_values_environments( p, val );
-                       break;
-               
-               case KEY_INDEX_FORMS:
-                       if ( subkeys )
-                               print_subpath_forms( p, subkeys );
-                       if ( val )
-                               print_subpath_values_forms( p, val );
-                       break;
-                       
-               case KEY_INDEX_PRINTER:
-                       if ( subkeys )
-                               print_subpath_printers( p, subkeys );
-                       if ( val )
-                               print_subpath_values_printers( p, val );
-                       break;
-       
-               /* default case for top level key that has no handler */
-               
-               default:
-                       break;
-       }
-       
-       
-       
-       return result;
-
-}
-/**********************************************************************
- Enumerate registry subkey names given a registry path.  
- Caller is responsible for freeing memory to **subkeys
- *********************************************************************/
-int printing_subkey_info( char *key, REGSUBKEY_CTR *subkey_ctr )
-{
-       char            *path;
-       BOOL            top_level = False;
-       int             num_subkeys = 0;
-       
-       DEBUG(10,("printing_subkey_info: key=>[%s]\n", key));
-       
-       path = trim_reg_path( key );
-       
-       /* check to see if we are dealing with the top level key */
-       
-       if ( !path )
-               top_level = True;
-               
-       if ( top_level ) {
-               for ( num_subkeys=0; num_subkeys<MAX_TOP_LEVEL_KEYS; num_subkeys++ )
-                       regsubkey_ctr_addkey( subkey_ctr, top_level_keys[num_subkeys] );
-       }
-       else
-               num_subkeys = handle_printing_subpath( path, subkey_ctr, NULL );
-       
-       SAFE_FREE( path );
-       
-       return num_subkeys;
-}
-
-/**********************************************************************
- Enumerate registry values given a registry path.  
- Caller is responsible for freeing memory 
- *********************************************************************/
-
-int printing_value_info( char *key, REGVAL_CTR *val )
-{
-       char            *path;
-       BOOL            top_level = False;
-       int             num_values = 0;
-       
-       DEBUG(10,("printing_value_info: key=>[%s]\n", key));
-       
-       path = trim_reg_path( key );
-       
-       /* check to see if we are dealing with the top level key */
-       
-       if ( !path )
-               top_level = True;
-       
-       /* fill in values from the getprinterdata_printer_server() */
-       if ( top_level )
-               num_values = 0;
-       else
-               num_values = handle_printing_subpath( path, NULL, val );
-               
-       
-       return num_values;
-}
-
-/**********************************************************************
- Stub function which always returns failure since we don't want
- people storing printing information directly via regostry calls
- (for now at least)
- *********************************************************************/
-
-BOOL printing_store_subkey( char *key, REGSUBKEY_CTR *subkeys )
-{
-       return False;
-}
-
-/**********************************************************************
- Stub function which always returns failure since we don't want
- people storing printing information directly via regostry calls
- (for now at least)
- *********************************************************************/
-
-BOOL printing_store_value( char *key, REGVAL_CTR *val )
-{
-       return False;
-}
-
-/* 
- * Table of function pointers for accessing printing data
- */
-REGISTRY_OPS printing_ops = {
-       printing_subkey_info,
-       printing_value_info,
-       printing_store_subkey,
-       printing_store_value
-};
-
-