diff options
author | Andrew Tridgell <tridge@samba.org> | 2003-12-01 00:17:30 +0000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2003-12-01 00:17:30 +0000 |
commit | 7602aa50fd591e63393def79d55302a22e77c387 (patch) | |
tree | 9233e0963192d8c6e9ee704a18cd2d3ca133392a | |
parent | fa062af11ada2cf1c58465447ea711ec4b9b3a12 (diff) | |
download | samba-7602aa50fd591e63393def79d55302a22e77c387.tar.gz samba-7602aa50fd591e63393def79d55302a22e77c387.tar.bz2 samba-7602aa50fd591e63393def79d55302a22e77c387.zip |
* got rid of UNISTR2 and everything that depends on it
* removed a bunch of code that needs to be rewritten using the new
interfaces
(This used to be commit 9b02b486ef5906516f8cad79dbff5e3dd54cde66)
-rw-r--r-- | source4/Makefile.in | 2 | ||||
-rw-r--r-- | source4/auth/auth_util.c | 223 | ||||
-rw-r--r-- | source4/groupdb/mapping.c | 1340 | ||||
-rw-r--r-- | source4/include/auth.h | 7 | ||||
-rw-r--r-- | source4/include/mapping.h | 1 | ||||
-rw-r--r-- | source4/include/rpc_dce.h | 289 | ||||
-rw-r--r-- | source4/include/rpc_lsa.h | 599 | ||||
-rw-r--r-- | source4/include/rpc_misc.h | 335 | ||||
-rw-r--r-- | source4/include/rpc_netlogon.h | 838 | ||||
-rw-r--r-- | source4/lib/util_unistr.c | 40 | ||||
-rw-r--r-- | source4/libcli/auth/ntlmssp.h | 3 | ||||
-rw-r--r-- | source4/libcli/util/credentials.c | 194 | ||||
-rw-r--r-- | source4/passdb/pdb_interface.c | 8 | ||||
-rw-r--r-- | source4/printing/nt_printing.c | 4887 | ||||
-rw-r--r-- | source4/registry/reg_printing.c | 829 |
15 files changed, 3 insertions, 9592 deletions
diff --git a/source4/Makefile.in b/source4/Makefile.in index 6a9017bbe1..f0e9574f4b 100644 --- a/source4/Makefile.in +++ b/source4/Makefile.in @@ -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 diff --git a/source4/auth/auth_util.c b/source4/auth/auth_util.c index 580b96142e..db208008ae 100644 --- a/source4/auth/auth_util.c +++ b/source4/auth/auth_util.c @@ -863,228 +863,6 @@ NTSTATUS make_server_info_guest(auth_serversupplied_info **server_info) } /*************************************************************************** - 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 index 958d6ded49..0000000000 --- a/source4/groupdb/mapping.c +++ /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; -} - diff --git a/source4/include/auth.h b/source4/include/auth.h index e37f181082..89e46e3782 100644 --- a/source4/include/auth.h +++ b/source4/include/auth.h @@ -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; diff --git a/source4/include/mapping.h b/source4/include/mapping.h index d4f2d28e6a..fd124034cf 100644 --- a/source4/include/mapping.h +++ b/source4/include/mapping.h @@ -50,7 +50,6 @@ typedef struct _GROUP_MAP { fstring nt_name; fstring comment; uint32 systemaccount; - PRIVILEGE_SET priv_set; } GROUP_MAP; typedef struct _PRIVS { diff --git a/source4/include/rpc_dce.h b/source4/include/rpc_dce.h index 6a8c650650..405bcc0caa 100644 --- a/source4/include/rpc_dce.h +++ b/source4/include/rpc_dce.h @@ -26,295 +26,6 @@ #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 */ diff --git a/source4/include/rpc_lsa.h b/source4/include/rpc_lsa.h index c091e73321..d4040af3aa 100644 --- a/source4/include/rpc_lsa.h +++ b/source4/include/rpc_lsa.h @@ -78,37 +78,6 @@ /* 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 */ diff --git a/source4/include/rpc_misc.h b/source4/include/rpc_misc.h index 06ad760c58..ac8a3c80c8 100644 --- a/source4/include/rpc_misc.h +++ b/source4/include/rpc_misc.h @@ -80,21 +80,6 @@ #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 */ diff --git a/source4/include/rpc_netlogon.h b/source4/include/rpc_netlogon.h index fb849f8238..68a3e42cf1 100644 --- a/source4/include/rpc_netlogon.h +++ b/source4/include/rpc_netlogon.h @@ -67,844 +67,6 @@ #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 */ diff --git a/source4/lib/util_unistr.c b/source4/lib/util_unistr.c index 3e3430d147..5e48d716b9 100644 --- a/source4/lib/util_unistr.c +++ b/source4/lib/util_unistr.c @@ -159,46 +159,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. ********************************************************************/ diff --git a/source4/libcli/auth/ntlmssp.h b/source4/libcli/auth/ntlmssp.h index 681d4071db..c57646ca31 100644 --- a/source4/libcli/auth/ntlmssp.h +++ b/source4/libcli/auth/ntlmssp.h @@ -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; diff --git a/source4/libcli/util/credentials.c b/source4/libcli/util/credentials.c index 0d521bae8a..2c8f7e7423 100644 --- a/source4/libcli/util/credentials.c +++ b/source4/libcli/util/credentials.c @@ -19,197 +19,3 @@ */ #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; -} diff --git a/source4/passdb/pdb_interface.c b/source4/passdb/pdb_interface.c index ceb4ad771e..43f07684c2 100644 --- a/source4/passdb/pdb_interface.c +++ b/source4/passdb/pdb_interface.c @@ -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 index 017dade404..0000000000 --- a/source4/printing/nt_printing.c +++ /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", ®val_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( ©->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 = ¤t_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 index 619ffc7ee7..0000000000 --- a/source4/registry/reg_printing.c +++ /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 -}; - - |