Hi, here's a patch witch add a lot more UF flags for userAccountControl
add details flags for sAMAccountType and groupType and make it possible to hold NT_STATUS codes inside of ADS_STATUS I use this for my new sam_ads module :-) It depends on a change abartlet want to do ( include some parts of smb.h befor ads.h) metze ----------------------------------------------------------------------------- Stefan "metze" Metzmacher <[EMAIL PROTECTED]>
diff -Npur --exclude=CVS --exclude=*.bak HEAD/source/libads/ads_status.c HEAD-fix/source/libads/ads_status.c --- HEAD/source/libads/ads_status.c Wed Jan 30 07:08:18 2002 +++ HEAD-fix/source/libads/ads_status.c Thu Sep 5 13:10:34 2002 @@ -30,19 +30,49 @@ ADS_STATUS ads_build_error(enum ads_erro int rc, int minor_status) { ADS_STATUS ret; - ret.error_type = etype; - ret.rc = rc; + + if (etype == ADS_ERROR_NT) { + DEBUG(0,("don't use ads_build_error with ADS_ERROR_NT!\n")); + ret.err.rc = -1; + ret.error_type = ADS_ERROR_SYSTEM; + ret.minor_status = 0; + return ret; + } + + ret.err.rc = rc; + ret.error_type = etype; ret.minor_status = minor_status; return ret; } +ADS_STATUS ads_build_nt_error(enum ads_error_type etype, + NTSTATUS nt_status) +{ + ADS_STATUS ret; + + if (etype != ADS_ERROR_NT) { + DEBUG(0,("don't use ads_build_nt_error without ADS_ERROR_NT!\n")); + ret.err.rc = -1; + ret.error_type = ADS_ERROR_SYSTEM; + ret.minor_status = 0; + return ret; + } + ret.err.nt_status = nt_status; + ret.error_type = etype; + ret.minor_status = 0; + return ret; +} + /* do a rough conversion between ads error codes and NT status codes we'll need to fill this in more */ -NTSTATUS ads_ntstatus(ADS_STATUS rc) +NTSTATUS ads_ntstatus(ADS_STATUS status) { - if (ADS_ERR_OK(rc)) return NT_STATUS_OK; + if (status.error_type == ADS_ERROR_NT){ + return status.err.nt_status; + } + if (ADS_ERR_OK(status)) return NT_STATUS_OK; return NT_STATUS_UNSUCCESSFUL; } @@ -59,14 +89,14 @@ const char *ads_errstr(ADS_STATUS status switch (status.error_type) { case ADS_ERROR_SYSTEM: - return strerror(status.rc); + return strerror(status.err.rc); #ifdef HAVE_LDAP case ADS_ERROR_LDAP: - return ldap_err2string(status.rc); + return ldap_err2string(status.err.rc); #endif #ifdef HAVE_KRB5 case ADS_ERROR_KRB5: - return error_message(status.rc); + return error_message(status.err.rc); #endif #ifdef HAVE_GSSAPI case ADS_ERROR_GSS: @@ -76,7 +106,7 @@ const char *ads_errstr(ADS_STATUS status gss_buffer_desc msg1, msg2; msg1.value = NULL; msg2.value = NULL; - gss_display_status(&minor, status.rc, GSS_C_GSS_CODE, + gss_display_status(&minor, status.err.rc, GSS_C_GSS_CODE, GSS_C_NULL_OID, &msg_ctx, &msg1); gss_display_status(&minor, status.minor_status, GSS_C_MECH_CODE, GSS_C_NULL_OID, &msg_ctx, &msg2); @@ -86,6 +116,8 @@ const char *ads_errstr(ADS_STATUS status return ret; } #endif + case ADS_ERROR_NT: + return nt_errstr(ads_ntstatus(status)); default: return "Unknown ADS error type!? (not compiled in?)"; } diff -Npur --exclude=CVS --exclude=*.bak HEAD/source/libads/ads_utils.c HEAD-fix/source/libads/ads_utils.c --- HEAD/source/libads/ads_utils.c Thu Jan 1 01:00:00 1970 +++ HEAD-fix/source/libads/ads_utils.c Thu Sep 5 05:20:04 2002 @@ -0,0 +1,75 @@ +/* + Unix SMB/CIFS implementation. + ads (active directory) utility library + + Copyright (C) Stefan (metze) Metzmacher 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. +*/ + +#include "includes.h" + +#ifdef HAVE_ADS + + +/* +translated the ACB_CTRL Flags to UserFlags (userAccountControl) +*/ +uint32 ads_acb2uf(uint16 acb) +{ + uint32 uf = 0x00000000; + + if (acb & ACB_DISABLED) uf |= UF_ACCOUNTDISABLE; + if (acb & ACB_HOMDIRREQ) uf |= UF_HOMEDIR_REQUIRED; + if (acb & ACB_PWNOTREQ) uf |= UF_PASSWD_NOTREQD; + if (acb & ACB_TEMPDUP) uf |= UF_TEMP_DUPLICATE_ACCOUNT; + if (acb & ACB_NORMAL) uf |= UF_NORMAL_ACCOUNT; + if (acb & ACB_MNS) uf |= UF_MNS_LOGON_ACCOUNT; + if (acb & ACB_DOMTRUST) uf |= UF_INTERDOMAIN_TRUST_ACCOUNT; + if (acb & ACB_WSTRUST) uf |= UF_WORKSTATION_TRUST_ACCOUNT; + if (acb & ACB_SVRTRUST) uf |= UF_SERVER_TRUST_ACCOUNT; + if (acb & ACB_PWNOEXP) uf |= UF_DONT_EXPIRE_PASSWD; + if (acb & ACB_AUTOLOCK) uf |= UF_LOCKOUT; + + return uf; +} + +/* translated the UserFlags (userAccountControl) to ACB_CTRL Flags */ +uint16 ads_uf2acb(uint32 uf) +{ + uint16 acb = 0x0000; + + if (uf & UF_ACCOUNTDISABLE) acb |= ACB_DISABLED; + if (uf & UF_HOMEDIR_REQUIRED) acb |= ACB_HOMDIRREQ; + if (uf & UF_PASSWD_NOTREQD) acb |= ACB_PWNOTREQ; + if (uf & UF_MNS_LOGON_ACCOUNT) acb |= ACB_MNS; + if (uf & UF_DONT_EXPIRE_PASSWD) acb |= ACB_PWNOEXP; + if (uf & UF_LOCKOUT) acb |= ACB_AUTOLOCK; + + switch (uf & UF_ACCOUNT_TYPE_MASK) + { + case UF_TEMP_DUPLICATE_ACCOUNT: acb |= ACB_TEMPDUP;break; + + case UF_NORMAL_ACCOUNT: acb |= ACB_NORMAL;break; + case UF_INTERDOMAIN_TRUST_ACCOUNT: acb |= ACB_DOMTRUST;break; + case UF_WORKSTATION_TRUST_ACCOUNT: acb |= ACB_WSTRUST;break; + case UF_SERVER_TRUST_ACCOUNT: acb |= ACB_SVRTRUST;break; + /*Fix Me: what should we do here? */ + default: acb |= ACB_NORMAL;break; + } + + return acb; +} + +#endif diff -Npur --exclude=CVS --exclude=*.bak --exclude=*.o --exclude=*.bak HEAD/source/utils/net_ads.c HEAD-fix/source/utils/net_ads.c --- HEAD/source/utils/net_ads.c Sat Aug 31 15:36:31 2002 +++ HEAD-fix/source/utils/net_ads.c Thu Sep 5 13:29:34 2002 @@ -635,7 +635,7 @@ int net_ads_join(int argc, const char ** rc = ads_search_dn(ads, &res, dn, NULL); ads_msgfree(ads, res); - if (rc.error_type == ADS_ERROR_LDAP && rc.rc == LDAP_NO_SUCH_OBJECT) { + if (rc.error_type == ADS_ERROR_LDAP && rc.err.rc == LDAP_NO_SUCH_OBJECT) { d_printf("ads_join_realm: organizational unit %s does not exist (dn:%s)\n", org_unit, dn); return -1; diff -Npur --exclude=CVS --exclude=*.bak --exclude=*.o --exclude=*.bak HEAD/source/nsswitch/winbindd_ads.c HEAD-fix/source/nsswitch/winbindd_ads.c --- HEAD/source/nsswitch/winbindd_ads.c Sat Aug 17 19:21:13 2002 +++ HEAD-fix/source/nsswitch/winbindd_ads.c Thu Sep 5 13:15:20 2002 @@ -143,7 +143,7 @@ static ADS_STRUCT *ads_cached_connection /* if we get ECONNREFUSED then it might be a NT4 server, fall back to MSRPC */ if (status.error_type == ADS_ERROR_SYSTEM && - status.rc == ECONNREFUSED) { + status.err.rc == ECONNREFUSED) { DEBUG(1,("Trying MSRPC methods\n")); domain->methods = &msrpc_methods; } @@ -170,9 +170,9 @@ static void sid_from_rid(struct winbindd static enum SID_NAME_USE ads_atype_map(uint32 atype) { switch (atype & 0xF0000000) { - case ATYPE_GROUP: + case ATYPE_GLOBAL_GROUP: return SID_NAME_DOM_GRP; - case ATYPE_USER: + case ATYPE_ACCOUNT: return SID_NAME_USER; default: DEBUG(1,("hmm, need to map account type 0x%x\n", atype)); @@ -339,7 +339,7 @@ static NTSTATUS enum_dom_groups(struct w if (!ads_pull_uint32(ads, msg, "sAMAccountType", &account_type) || - !(account_type & ATYPE_GROUP)) continue; + !(account_type & ATYPE_GLOBAL_GROUP)) continue; name = pull_username(ads, mem_ctx, msg); gecos = ads_pull_string(ads, mem_ctx, msg, "name"); diff -Npur --exclude=CVS --exclude=*.bak --exclude=*.o --exclude=.#* HEAD/source/include/ads.h HEAD-fix/source/include/ads.h --- HEAD/source/include/ads.h Sat Aug 17 19:21:11 2002 +++ HEAD-fix/source/include/ads.h Thu Sep 5 15:25:02 2002 @@ -92,11 +92,14 @@ typedef struct { /* there are 4 possible types of errors the ads subsystem can produce */ enum ads_error_type {ADS_ERROR_KRB5, ADS_ERROR_GSS, - ADS_ERROR_LDAP, ADS_ERROR_SYSTEM}; + ADS_ERROR_LDAP, ADS_ERROR_SYSTEM, ADS_ERROR_NT}; typedef struct { enum ads_error_type error_type; - int rc; + union err_state{ + int rc; + NTSTATUS nt_status; + } err; /* For error_type = ADS_ERROR_GSS minor_status describe GSS API error */ /* Where rc represents major_status of GSS API error */ int minor_status; @@ -109,12 +112,14 @@ typedef void **ADS_MODLIST; #endif /* macros to simplify error returning */ -#define ADS_ERROR(rc) ads_build_error(ADS_ERROR_LDAP, rc, 0) +#define ADS_ERROR(rc) ADS_ERROR_LDAP(rc) +#define ADS_ERROR_LDAP(rc) ads_build_error(ADS_ERROR_LDAP, rc, 0) #define ADS_ERROR_SYSTEM(rc) ads_build_error(ADS_ERROR_SYSTEM, rc?rc:EINVAL, 0) #define ADS_ERROR_KRB5(rc) ads_build_error(ADS_ERROR_KRB5, rc, 0) #define ADS_ERROR_GSS(rc, minor) ads_build_error(ADS_ERROR_GSS, rc, minor) +#define ADS_ERROR_NT(rc) ads_build_nt_error(ADS_ERROR_NT,rc) -#define ADS_ERR_OK(status) ((status).rc == 0) +#define ADS_ERR_OK(status) ((status).error_type == +ADS_ERROR_NT)?NT_STATUS_IS_OK((status).err.nt_status):((status).err.rc == 0) #define ADS_SUCCESS ADS_ERROR(0) /* time between reconnect attempts */ @@ -128,23 +133,100 @@ typedef void **ADS_MODLIST; #define ADS_NO_REFERRALS_OID "1.2.840.113556.1.4.1339" #define ADS_SERVER_SORT_OID "1.2.840.113556.1.4.473" -#define UF_DONT_EXPIRE_PASSWD 0x10000 -#define UF_MNS_LOGON_ACCOUNT 0x20000 -#define UF_SMARTCARD_REQUIRED 0x40000 -#define UF_TRUSTED_FOR_DELEGATION 0x80000 -#define UF_NOT_DELEGATED 0x100000 -#define UF_USE_DES_KEY_ONLY 0x200000 -#define UF_DONT_REQUIRE_PREAUTH 0x400000 - -#define UF_TEMP_DUPLICATE_ACCOUNT 0x0100 -#define UF_NORMAL_ACCOUNT 0x0200 -#define UF_INTERDOMAIN_TRUST_ACCOUNT 0x0800 -#define UF_WORKSTATION_TRUST_ACCOUNT 0x1000 -#define UF_SERVER_TRUST_ACCOUNT 0x2000 - -/* account types */ -#define ATYPE_GROUP 0x10000000 -#define ATYPE_USER 0x30000000 +/* UserFlags for userAccountControl */ +#define UF_SCRIPT 0x00000001 +#define UF_ACCOUNTDISABLE 0x00000002 +#define UF_UNUSED_1 0x00000004 +#define UF_HOMEDIR_REQUIRED 0x00000008 + +#define UF_LOCKOUT 0x00000010 +#define UF_PASSWD_NOTREQD 0x00000020 +#define UF_PASSWD_CANT_CHANGE 0x00000040 +#define UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED 0x00000080 + +#define UF_TEMP_DUPLICATE_ACCOUNT 0x00000100 +#define UF_NORMAL_ACCOUNT 0x00000200 +#define UF_UNUSED_2 0x00000400 +#define UF_INTERDOMAIN_TRUST_ACCOUNT 0x00000800 + +#define UF_WORKSTATION_TRUST_ACCOUNT 0x00001000 +#define UF_SERVER_TRUST_ACCOUNT 0x00002000 +#define UF_UNUSED_3 0x00004000 +#define UF_UNUSED_4 0x00008000 + +#define UF_DONT_EXPIRE_PASSWD 0x00010000 +#define UF_MNS_LOGON_ACCOUNT 0x00020000 +#define UF_SMARTCARD_REQUIRED 0x00040000 +#define UF_TRUSTED_FOR_DELEGATION 0x00080000 + +#define UF_NOT_DELEGATED 0x00100000 +#define UF_USE_DES_KEY_ONLY 0x00200000 +#define UF_DONT_REQUIRE_PREAUTH 0x00400000 +#define UF_UNUSED_5 0x00800000 + +#define UF_UNUSED_6 0x01000000 +#define UF_UNUSED_7 0x02000000 +#define UF_UNUSED_8 0x04000000 +#define UF_UNUSED_9 0x08000000 + +#define UF_UNUSED_10 0x10000000 +#define UF_UNUSED_11 0x20000000 +#define UF_UNUSED_12 0x40000000 +#define UF_UNUSED_13 0x80000000 + +#define UF_MACHINE_ACCOUNT_MASK (\ + UF_INTERDOMAIN_TRUST_ACCOUNT |\ + UF_WORKSTATION_TRUST_ACCOUNT |\ + UF_SERVER_TRUST_ACCOUNT \ + ) + +#define UF_ACCOUNT_TYPE_MASK (\ + UF_TEMP_DUPLICATE_ACCOUNT |\ + UF_NORMAL_ACCOUNT |\ + UF_INTERDOMAIN_TRUST_ACCOUNT |\ + UF_WORKSTATION_TRUST_ACCOUNT |\ + UF_SERVER_TRUST_ACCOUNT \ + ) + +#define UF_SETTABLE_BITS (\ + UF_SCRIPT |\ + UF_ACCOUNTDISABLE |\ + UF_HOMEDIR_REQUIRED |\ + UF_LOCKOUT |\ + UF_PASSWD_NOTREQD |\ + UF_PASSWD_CANT_CHANGE |\ + UF_ACCOUNT_TYPE_MASK | \ + UF_DONT_EXPIRE_PASSWD | \ + UF_MNS_LOGON_ACCOUNT |\ + UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED |\ + UF_SMARTCARD_REQUIRED |\ + UF_TRUSTED_FOR_DELEGATION |\ + UF_NOT_DELEGATED |\ + UF_USE_DES_KEY_ONLY |\ + UF_DONT_REQUIRE_PREAUTH \ + ) + +/* sAMAccountType */ +#define ATYPE_NORMAL_ACCOUNT 0x30000000 /* 805306368 */ +#define ATYPE_WORKSTATION_TRUST 0x30000001 /* 805306369 */ +#define ATYPE_INTERDOMAIN_TRUST 0x30000002 /* 805306370 */ +#define ATYPE_SECURITY_GLOBAL_GROUP 0x10000000 /* 268435456 */ +#define ATYPE_DISTRIBUTION_GLOBAL_GROUP 0x10000001 /* 268435457 */ +#define ATYPE_DISTRIBUTION_UNIVERSAL_GROUP AT_DISTRIBUTION_GLOBAL_GROUP +#define ATYPE_SECURITY_LOCAL_GROUP 0x20000000 /* 536870912 */ +#define ATYPE_DISTRIBUTION_LOCAL_GROUP 0x20000001 /* 536870913 */ + +#define ATYPE_ACCOUNT ATYPE_NORMAL_ACCOUNT /* 0x30000000 +805306368 */ +#define ATYPE_GLOBAL_GROUP ATYPE_SECURITY_GLOBAL_GROUP /* 0x10000000 +268435456 */ +#define ATYPE_LOCAL_GROUP ATYPE_SECURITY_LOCAL_GROUP /* 0x20000000 +536870912 */ + +/* groupType */ +#define GTYPE_SECURITY_BUILTIN_LOCAL_GROUP 0x80000005 /* -2147483643 */ +#define GTYPE_SECURITY_DOMAIN_LOCAL_GROUP 0x80000004 /* -2147483644 */ +#define GTYPE_SECURITY_GLOBAL_GROUP 0x80000002 /* -2147483646 */ +#define GTYPE_DISTRIBUTION_GLOBAL_GROUP 0x00000002 /* 2 */ +#define GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP 0x00000004 /* 4 */ +#define GTYPE_DISTRIBUTION_UNIVERSAL_GROUP 0x00000008 /* 8 */ /* Mailslot or cldap getdcname response flags */ #define ADS_PDC 0x00000001 /* DC is PDC */