~ubuntu-branches/ubuntu/vivid/samba/vivid

« back to all changes in this revision

Viewing changes to source3/winbindd/idmap_ad.c

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2011-12-21 13:18:04 UTC
  • mfrom: (0.39.21 sid)
  • Revision ID: package-import@ubuntu.com-20111221131804-xtlr39wx6njehxxr
Tags: 2:3.6.1-3ubuntu1
* Merge from Debian testing.  Remaining changes:
  + debian/patches/VERSION.patch:
    - set SAMBA_VERSION_SUFFIX to Ubuntu.
  + debian/patches/error-trans.fix-276472:
    - Add the translation of Unix Error code -ENOTSUP to NT Error Code
    - NT_STATUS_NOT_SUPPORTED to prevent the Permission denied error.
  + debian/smb.conf:
    - add "(Samba, Ubuntu)" to server string.
    - comment out the default [homes] share, and add a comment about
      "valid users = %S" to show users how to restrict access to
      \\server\username to only username.
    - Set 'usershare allow guests', so that usershare admins are 
      allowed to create public shares in addition to authenticated
      ones.
    - add map to guest = Bad user, maps bad username to guest access.
  + debian/samba-common.config:
    - Do not change priority to high if dhclient3 is installed.
    - Use priority medium instead of high for the workgroup question.
  + debian/control:
    - Don't build against or suggest ctdb.
    - Add dependency on samba-common-bin to samba.
  + Add ufw integration:
    - Created debian/samba.ufw.profile
    - debian/rules, debian/samba.dirs, debian/samba.files: install
      profile
    - debian/control: have samba suggest ufw
  + Add apport hook:
    - Created debian/source_samba.py.
    - debian/rules, debian/samba.dirs, debian/samba-common-bin.files: install
  + Switch to upstart:
    - Add debian/samba.{nmbd,smbd}.upstart.
  + debian/samba.logrotate, debian/samba-common.dhcp, debian/samba.if-up:
    - Make them upstart compatible
  + debian/samba.postinst: 
    - Avoid scary pdbedit warnings on first import.
  + debian/samba-common.postinst: Add more informative error message for
    the case where smb.conf was manually deleted
  + debian/patches/fix-debuglevel-name-conflict.patch: don't use 'debug_level'
    as a global variable name in an NSS module 
  + Dropped:
    - debian/patches/error-trans.fix-276472
    - debian/patches/fix-debuglevel-name-conflict.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
9
9
 * Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
10
10
 * Copyright (C) Gerald (Jerry) Carter 2004-2007
11
11
 * Copyright (C) Luke Howard 2001-2004
12
 
 * Copyright (C) Michael Adam 2008
 
12
 * Copyright (C) Michael Adam 2008,2010
13
13
 *
14
14
 * This program is free software; you can redistribute it and/or modify
15
15
 * it under the terms of the GNU General Public License as published by
27
27
 
28
28
#include "includes.h"
29
29
#include "winbindd.h"
 
30
#include "../libds/common/flags.h"
 
31
#include "ads.h"
 
32
#include "libads/ldap_schema.h"
 
33
#include "nss_info.h"
 
34
#include "secrets.h"
 
35
#include "idmap.h"
 
36
#include "../libcli/ldap/ldap_ndr.h"
 
37
#include "../libcli/security/security.h"
30
38
 
31
39
#undef DBGC_CLASS
32
40
#define DBGC_CLASS DBGC_IDMAP
43
51
} while (0)
44
52
 
45
53
struct idmap_ad_context {
46
 
        uint32_t filter_low_id;
47
 
        uint32_t filter_high_id;
48
54
        ADS_STRUCT *ads;
49
55
        struct posix_schema *ad_schema;
50
56
        enum wb_posix_mapping ad_map_type; /* WB_POSIX_MAP_UNKNOWN */
94
100
                        ads_destroy( &ads );
95
101
                        ads_kdestroy(WINBIND_CCACHE_NAME);
96
102
                        ctx->ads = NULL;
97
 
                        TALLOC_FREE( ctx->ad_schema );
98
103
                }
99
104
        }
100
105
 
137
142
        /* setup server affinity */
138
143
 
139
144
        get_dc_name(dom->name, realm, dc_name, &dc_ip );
140
 
        
 
145
 
141
146
        status = ads_connect(ads);
142
147
        if (!ADS_ERR_OK(status)) {
143
 
                DEBUG(1, ("ad_idmap_init: failed to connect to AD\n"));
 
148
                DEBUG(1, ("ad_idmap_cached_connection_internal: failed to "
 
149
                          "connect to AD\n"));
144
150
                ads_destroy(&ads);
145
151
                return status;
146
152
        }
180
186
             (ctx->ad_map_type ==  WB_POSIX_MAP_SFU20) ||
181
187
             (ctx->ad_map_type ==  WB_POSIX_MAP_RFC2307) )
182
188
        {
183
 
                status = ads_check_posix_schema_mapping(NULL, ctx->ads, ctx->ad_map_type, &ctx->ad_schema);
 
189
                status = ads_check_posix_schema_mapping(
 
190
                        ctx, ctx->ads, ctx->ad_map_type, &ctx->ad_schema);
184
191
                if ( !ADS_ERR_OK(status) ) {
185
192
                        DEBUG(2,("ad_idmap_cached_connection: Failed to obtain schema details!\n"));
186
193
                }
187
194
        }
188
 
        
 
195
 
189
196
        return status;
190
197
}
191
198
 
 
199
static int idmap_ad_context_destructor(struct idmap_ad_context *ctx)
 
200
{
 
201
        if (ctx->ads != NULL) {
 
202
                /* we own this ADS_STRUCT so make sure it goes away */
 
203
                ctx->ads->is_mine = True;
 
204
                ads_destroy( &ctx->ads );
 
205
                ctx->ads = NULL;
 
206
        }
 
207
        return 0;
 
208
}
 
209
 
192
210
/************************************************************************
193
211
 ***********************************************************************/
194
212
 
195
 
static NTSTATUS idmap_ad_initialize(struct idmap_domain *dom,
196
 
                                    const char *params)
 
213
static NTSTATUS idmap_ad_initialize(struct idmap_domain *dom)
197
214
{
198
215
        struct idmap_ad_context *ctx;
199
216
        char *config_option;
200
 
        const char *range = NULL;
201
217
        const char *schema_mode = NULL; 
202
218
 
203
 
        if ( (ctx = TALLOC_ZERO_P(dom, struct idmap_ad_context)) == NULL ) {
 
219
        ctx = TALLOC_ZERO_P(dom, struct idmap_ad_context);
 
220
        if (ctx == NULL) {
204
221
                DEBUG(0, ("Out of memory!\n"));
205
222
                return NT_STATUS_NO_MEMORY;
206
223
        }
 
224
        talloc_set_destructor(ctx, idmap_ad_context_destructor);
207
225
 
208
 
        if ( (config_option = talloc_asprintf(ctx, "idmap config %s", dom->name)) == NULL ) {
 
226
        config_option = talloc_asprintf(ctx, "idmap config %s", dom->name);
 
227
        if (config_option == NULL) {
209
228
                DEBUG(0, ("Out of memory!\n"));
210
229
                talloc_free(ctx);
211
230
                return NT_STATUS_NO_MEMORY;
212
231
        }
213
232
 
214
 
        /* load ranges */
215
 
        range = lp_parm_const_string(-1, config_option, "range", NULL);
216
 
        if (range && range[0]) {
217
 
                if ((sscanf(range, "%u - %u", &ctx->filter_low_id, &ctx->filter_high_id) != 2) ||
218
 
                    (ctx->filter_low_id > ctx->filter_high_id)) {
219
 
                        DEBUG(1, ("ERROR: invalid filter range [%s]", range));
220
 
                        ctx->filter_low_id = 0;
221
 
                        ctx->filter_high_id = 0;
222
 
                }
223
 
        }
224
 
 
225
233
        /* default map type */
226
234
        ctx->ad_map_type = WB_POSIX_MAP_RFC2307;
227
235
 
267
275
 Search up to IDMAP_AD_MAX_IDS entries in maps for a match
268
276
 ***********************************************************************/
269
277
 
270
 
static struct id_map *find_map_by_sid(struct id_map **maps, DOM_SID *sid)
 
278
static struct id_map *find_map_by_sid(struct id_map **maps, struct dom_sid *sid)
271
279
{
272
280
        int i;
273
281
 
274
282
        for (i = 0; maps[i] && i<IDMAP_AD_MAX_IDS; i++) {
275
 
                if (sid_equal(maps[i]->sid, sid)) {
 
283
                if (dom_sid_equal(maps[i]->sid, sid)) {
276
284
                        return maps[i];
277
285
                }
278
286
        }
308
316
        for (i = 0; ids[i]; i++) {
309
317
                ids[i]->status = ID_UNKNOWN;
310
318
        }
311
 
        
 
319
 
312
320
        /* Only do query if we are online */
313
321
        if (idmap_is_offline()) {
314
322
                return NT_STATUS_FILE_IS_OFFLINE;
351
359
                                                          (unsigned long)ids[idx]->xid.id);
352
360
                        CHECK_ALLOC_DONE(u_filter);
353
361
                        break;
354
 
                                
 
362
 
355
363
                case ID_TYPE_GID:
356
364
                        if ( ! g_filter) {
357
365
                                g_filter = talloc_asprintf(memctx, "(&(|"
400
408
 
401
409
        entry = res;
402
410
        for (i = 0; (i < count) && entry; i++) {
403
 
                DOM_SID sid;
 
411
                struct dom_sid sid;
404
412
                enum id_type type;
405
413
                struct id_map *map;
406
414
                uint32_t id;
453
461
                        continue;
454
462
                }
455
463
 
456
 
                if ((id == 0) ||
457
 
                    (ctx->filter_low_id && (id < ctx->filter_low_id)) ||
458
 
                    (ctx->filter_high_id && (id > ctx->filter_high_id))) {
 
464
                if (!idmap_unix_id_is_in_range(id, dom)) {
459
465
                        DEBUG(5, ("Requested id (%u) out of range (%u - %u). Filtered!\n",
460
 
                                id, ctx->filter_low_id, ctx->filter_high_id));
 
466
                                id, dom->low_id, dom->high_id));
461
467
                        continue;
462
468
                }
463
469
 
562
568
                                 ")(|",
563
569
                                 ATYPE_NORMAL_ACCOUNT, ATYPE_WORKSTATION_TRUST, ATYPE_INTERDOMAIN_TRUST,
564
570
                                 ATYPE_SECURITY_GLOBAL_GROUP, ATYPE_SECURITY_LOCAL_GROUP);
565
 
                
 
571
 
566
572
        CHECK_ALLOC_DONE(filter);
567
573
 
568
574
        bidx = idx;
570
576
 
571
577
                ids[idx]->status = ID_UNKNOWN;
572
578
 
573
 
                sidstr = sid_binstring(talloc_tos(), ids[idx]->sid);
 
579
                sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), ids[idx]->sid);
574
580
                filter = talloc_asprintf_append_buffer(filter, "(objectSid=%s)", sidstr);
575
 
                        
 
581
 
576
582
                TALLOC_FREE(sidstr);
577
583
                CHECK_ALLOC_DONE(filter);
578
584
        }
593
599
 
594
600
        entry = res;    
595
601
        for (i = 0; (i < count) && entry; i++) {
596
 
                DOM_SID sid;
 
602
                struct dom_sid sid;
597
603
                enum id_type type;
598
604
                struct id_map *map;
599
605
                uint32_t id;
651
657
                        DEBUG(1, ("Could not get unix ID\n"));
652
658
                        continue;
653
659
                }
654
 
                if ((id == 0) ||
655
 
                    (ctx->filter_low_id && (id < ctx->filter_low_id)) ||
656
 
                    (ctx->filter_high_id && (id > ctx->filter_high_id))) {
 
660
                if (!idmap_unix_id_is_in_range(id, dom)) {
657
661
                        DEBUG(5, ("Requested id (%u) out of range (%u - %u). Filtered!\n",
658
 
                                id, ctx->filter_low_id, ctx->filter_high_id));
 
662
                                id, dom->low_id, dom->high_id));
659
663
                        continue;
660
664
                }
661
665
 
679
683
 
680
684
        ret = NT_STATUS_OK;
681
685
 
682
 
        /* mark all unknwoni/expired ones as unmapped */
 
686
        /* mark all unknown/expired ones as unmapped */
683
687
        for (i = 0; ids[i]; i++) {
684
688
                if (ids[i]->status != ID_MAPPED) 
685
689
                        ids[i]->status = ID_UNMAPPED;
690
694
        return ret;
691
695
}
692
696
 
693
 
/************************************************************************
694
 
 ***********************************************************************/
695
 
 
696
 
static NTSTATUS idmap_ad_close(struct idmap_domain *dom)
697
 
{
698
 
        struct idmap_ad_context * ctx;
699
 
 
700
 
        ctx = talloc_get_type(dom->private_data, struct idmap_ad_context);
701
 
 
702
 
        if (ctx->ads != NULL) {
703
 
                /* we own this ADS_STRUCT so make sure it goes away */
704
 
                ctx->ads->is_mine = True;
705
 
                ads_destroy( &ctx->ads );
706
 
                ctx->ads = NULL;
707
 
        }
708
 
 
709
 
        TALLOC_FREE( ctx->ad_schema );
710
 
        
711
 
        return NT_STATUS_OK;
712
 
}
713
 
 
714
697
/*
715
698
 * nss_info_{sfu,sfu20,rfc2307}
716
699
 */
818
801
 ***********************************************************************/
819
802
 
820
803
static NTSTATUS nss_ad_get_info( struct nss_domain_entry *e, 
821
 
                                  const DOM_SID *sid, 
 
804
                                  const struct dom_sid *sid,
822
805
                                  TALLOC_CTX *mem_ctx,
823
 
                                  ADS_STRUCT *ads, 
824
 
                                  LDAPMessage *msg,
825
806
                                  const char **homedir,
826
807
                                  const char **shell,
827
808
                                  const char **gecos,
865
846
                return NT_STATUS_INVALID_PARAMETER;
866
847
        }
867
848
 
868
 
        /* See if we can use the ADS connection struct swe were given */
869
 
 
870
 
        if (ads) {
871
 
                DEBUG(10, ("nss_ad_get_info: using given ads connection and "
872
 
                           "LDAP message (%p)\n", msg));
873
 
 
874
 
                *homedir = ads_pull_string( ads, mem_ctx, msg, ctx->ad_schema->posix_homedir_attr );
875
 
                *shell   = ads_pull_string( ads, mem_ctx, msg, ctx->ad_schema->posix_shell_attr );
876
 
                *gecos   = ads_pull_string( ads, mem_ctx, msg, ctx->ad_schema->posix_gecos_attr );
877
 
 
878
 
                if (gid) {
879
 
                        if ( !ads_pull_uint32(ads, msg, ctx->ad_schema->posix_gidnumber_attr, gid ) )
880
 
                                *gid = (uint32)-1;
881
 
                }
882
 
 
883
 
                nt_status = NT_STATUS_OK;
884
 
                goto done;
885
 
        }
886
 
 
887
849
        /* Have to do our own query */
888
850
 
889
851
        DEBUG(10, ("nss_ad_get_info: no ads connection given, doing our "
894
856
        attrs[2] = ctx->ad_schema->posix_gecos_attr;
895
857
        attrs[3] = ctx->ad_schema->posix_gidnumber_attr;
896
858
 
897
 
        sidstr = sid_binstring(mem_ctx, sid);
 
859
        sidstr = ldap_encode_ndr_dom_sid(mem_ctx, sid);
898
860
        filter = talloc_asprintf(mem_ctx, "(objectSid=%s)", sidstr);
899
861
        TALLOC_FREE(sidstr);
900
862
 
1094
1056
        return nt_status;
1095
1057
}
1096
1058
 
1097
 
 
1098
 
/************************************************************************
1099
 
 ***********************************************************************/
1100
 
 
1101
 
static NTSTATUS nss_ad_close( void )
1102
 
{
1103
 
        /* nothing to do.  All memory is free()'d by the idmap close_fn() */
1104
 
 
1105
 
        return NT_STATUS_OK;
1106
 
}
1107
 
 
1108
1059
/************************************************************************
1109
1060
 Function dispatch tables for the idmap and nss plugins
1110
1061
 ***********************************************************************/
1113
1064
        .init            = idmap_ad_initialize,
1114
1065
        .unixids_to_sids = idmap_ad_unixids_to_sids,
1115
1066
        .sids_to_unixids = idmap_ad_sids_to_unixids,
1116
 
        .close_fn        = idmap_ad_close
1117
1067
};
1118
1068
 
1119
1069
/* The SFU and RFC2307 NSS plugins share everything but the init
1120
1070
   function which sets the intended schema model to use */
1121
 
  
 
1071
 
1122
1072
static struct nss_info_methods nss_rfc2307_methods = {
1123
1073
        .init           = nss_rfc2307_init,
1124
1074
        .get_nss_info   = nss_ad_get_info,
1125
1075
        .map_to_alias   = nss_ad_map_to_alias,
1126
1076
        .map_from_alias = nss_ad_map_from_alias,
1127
 
        .close_fn       = nss_ad_close
1128
1077
};
1129
1078
 
1130
1079
static struct nss_info_methods nss_sfu_methods = {
1132
1081
        .get_nss_info   = nss_ad_get_info,
1133
1082
        .map_to_alias   = nss_ad_map_to_alias,
1134
1083
        .map_from_alias = nss_ad_map_from_alias,
1135
 
        .close_fn       = nss_ad_close
1136
1084
};
1137
1085
 
1138
1086
static struct nss_info_methods nss_sfu20_methods = {
1140
1088
        .get_nss_info   = nss_ad_get_info,
1141
1089
        .map_to_alias   = nss_ad_map_to_alias,
1142
1090
        .map_from_alias = nss_ad_map_from_alias,
1143
 
        .close_fn       = nss_ad_close
1144
1091
};
1145
1092
 
1146
1093
 
1165
1112
                if ( !NT_STATUS_IS_OK(status_idmap_ad) )
1166
1113
                        return status_idmap_ad;         
1167
1114
        }
1168
 
        
 
1115
 
1169
1116
        if ( !NT_STATUS_IS_OK( status_nss_rfc2307 ) ) {
1170
1117
                status_nss_rfc2307 = smb_register_idmap_nss(SMB_NSS_INFO_INTERFACE_VERSION,
1171
1118
                                                            "rfc2307",  &nss_rfc2307_methods );