00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "includes.h"
00023 #include "winbindd.h"
00024
00025 #undef DBGC_CLASS
00026 #define DBGC_CLASS DBGC_IDMAP
00027
00028 struct idmap_rid_context {
00029 const char *domain_name;
00030 uint32_t low_id;
00031 uint32_t high_id;
00032 uint32_t base_rid;
00033 };
00034
00035
00036
00037
00038
00039
00040 static NTSTATUS idmap_rid_initialize(struct idmap_domain *dom)
00041 {
00042 NTSTATUS ret;
00043 struct idmap_rid_context *ctx;
00044 char *config_option = NULL;
00045 const char *range;
00046 uid_t low_uid = 0;
00047 uid_t high_uid = 0;
00048 gid_t low_gid = 0;
00049 gid_t high_gid = 0;
00050
00051 if ( (ctx = TALLOC_ZERO_P(dom, struct idmap_rid_context)) == NULL ) {
00052 DEBUG(0, ("Out of memory!\n"));
00053 return NT_STATUS_NO_MEMORY;
00054 }
00055
00056 config_option = talloc_asprintf(ctx, "idmap config %s", dom->name);
00057 if ( ! config_option) {
00058 DEBUG(0, ("Out of memory!\n"));
00059 ret = NT_STATUS_NO_MEMORY;
00060 goto failed;
00061 }
00062
00063 range = lp_parm_const_string(-1, config_option, "range", NULL);
00064 if ( !range ||
00065 (sscanf(range, "%u - %u", &ctx->low_id, &ctx->high_id) != 2) ||
00066 (ctx->low_id > ctx->high_id))
00067 {
00068 ctx->low_id = 0;
00069 ctx->high_id = 0;
00070 }
00071
00072
00073 if (!ctx->low_id && !ctx->high_id) {
00074 if (lp_idmap_uid(&low_uid, &high_uid)) {
00075 ctx->low_id = low_uid;
00076 ctx->high_id = high_uid;
00077 }
00078
00079 if (lp_idmap_gid(&low_gid, &high_gid)) {
00080 if ((ctx->low_id != low_gid) ||
00081 (ctx->high_id != high_uid)) {
00082 DEBUG(1, ("ERROR: idmap uid irange must match idmap gid range\n"));
00083 ret = NT_STATUS_UNSUCCESSFUL;
00084 goto failed;
00085 }
00086 }
00087 }
00088
00089 if (!ctx->low_id || !ctx->high_id) {
00090 DEBUG(1, ("ERROR: Invalid configuration, ID range missing or invalid\n"));
00091 ret = NT_STATUS_UNSUCCESSFUL;
00092 goto failed;
00093 }
00094
00095 ctx->base_rid = lp_parm_int(-1, config_option, "base_rid", 0);
00096 ctx->domain_name = talloc_strdup( ctx, dom->name );
00097
00098 dom->private_data = ctx;
00099 dom->initialized = True;
00100
00101 talloc_free(config_option);
00102 return NT_STATUS_OK;
00103
00104 failed:
00105 talloc_free(ctx);
00106 return ret;
00107 }
00108
00109 static NTSTATUS idmap_rid_id_to_sid(TALLOC_CTX *memctx, struct idmap_rid_context *ctx, struct id_map *map)
00110 {
00111 struct winbindd_domain *domain;
00112
00113
00114 if ((map->xid.id < ctx->low_id) || (map->xid.id > ctx->high_id)) {
00115 DEBUG(5, ("Requested id (%u) out of range (%u - %u). Filtered!\n",
00116 map->xid.id, ctx->low_id, ctx->high_id));
00117 return NT_STATUS_NONE_MAPPED;
00118 }
00119
00120 if ( (domain = find_domain_from_name_noinit(ctx->domain_name)) == NULL ) {
00121 return NT_STATUS_NO_SUCH_DOMAIN;
00122 }
00123
00124 sid_compose(map->sid, &domain->sid, map->xid.id - ctx->low_id + ctx->base_rid);
00125
00126
00127
00128
00129
00130 map->status = ID_MAPPED;
00131
00132 return NT_STATUS_OK;
00133 }
00134
00135
00136
00137
00138
00139 static NTSTATUS idmap_rid_sid_to_id(TALLOC_CTX *memctx, struct idmap_rid_context *ctx, struct id_map *map)
00140 {
00141 uint32_t rid;
00142
00143 sid_peek_rid(map->sid, &rid);
00144 map->xid.id = rid - ctx->base_rid + ctx->low_id;
00145
00146
00147
00148 if ((map->xid.id < ctx->low_id) || (map->xid.id > ctx->high_id)) {
00149 DEBUG(5, ("Requested id (%u) out of range (%u - %u). Filtered!\n",
00150 map->xid.id, ctx->low_id, ctx->high_id));
00151 map->status = ID_UNMAPPED;
00152 return NT_STATUS_NONE_MAPPED;
00153 }
00154
00155
00156
00157
00158
00159 map->status = ID_MAPPED;
00160
00161 return NT_STATUS_OK;
00162 }
00163
00164
00165
00166
00167
00168 static NTSTATUS idmap_rid_unixids_to_sids(struct idmap_domain *dom, struct id_map **ids)
00169 {
00170 struct idmap_rid_context *ridctx;
00171 TALLOC_CTX *ctx;
00172 NTSTATUS ret;
00173 int i;
00174
00175
00176 if ( ! dom->initialized) {
00177 ret = idmap_rid_initialize(dom);
00178 if ( ! NT_STATUS_IS_OK(ret)) {
00179 return ret;
00180 }
00181 }
00182
00183 ridctx = talloc_get_type(dom->private_data, struct idmap_rid_context);
00184
00185 ctx = talloc_new(dom);
00186 if ( ! ctx) {
00187 DEBUG(0, ("Out of memory!\n"));
00188 return NT_STATUS_NO_MEMORY;
00189 }
00190
00191 for (i = 0; ids[i]; i++) {
00192
00193 ret = idmap_rid_id_to_sid(ctx, ridctx, ids[i]);
00194
00195 if (( ! NT_STATUS_IS_OK(ret)) &&
00196 ( ! NT_STATUS_EQUAL(ret, NT_STATUS_NONE_MAPPED))) {
00197
00198 DEBUG(3, ("Unexpected error resolving an ID (%d)\n", ids[i]->xid.id));
00199 }
00200 }
00201
00202 talloc_free(ctx);
00203 return NT_STATUS_OK;
00204 }
00205
00206
00207
00208
00209
00210 static NTSTATUS idmap_rid_sids_to_unixids(struct idmap_domain *dom, struct id_map **ids)
00211 {
00212 struct idmap_rid_context *ridctx;
00213 TALLOC_CTX *ctx;
00214 NTSTATUS ret;
00215 int i;
00216
00217
00218 if ( ! dom->initialized) {
00219 ret = idmap_rid_initialize(dom);
00220 if ( ! NT_STATUS_IS_OK(ret)) {
00221 return ret;
00222 }
00223 }
00224
00225 ridctx = talloc_get_type(dom->private_data, struct idmap_rid_context);
00226
00227 ctx = talloc_new(dom);
00228 if ( ! ctx) {
00229 DEBUG(0, ("Out of memory!\n"));
00230 return NT_STATUS_NO_MEMORY;
00231 }
00232
00233 for (i = 0; ids[i]; i++) {
00234
00235 ret = idmap_rid_sid_to_id(ctx, ridctx, ids[i]);
00236
00237 if (( ! NT_STATUS_IS_OK(ret)) &&
00238 ( ! NT_STATUS_EQUAL(ret, NT_STATUS_NONE_MAPPED))) {
00239
00240 DEBUG(3, ("Unexpected error resolving a SID (%s)\n",
00241 sid_string_static(ids[i]->sid)));
00242 }
00243 }
00244
00245 talloc_free(ctx);
00246 return NT_STATUS_OK;
00247 }
00248
00249 static NTSTATUS idmap_rid_close(struct idmap_domain *dom)
00250 {
00251 if (dom->private_data) {
00252 TALLOC_FREE(dom->private_data);
00253 }
00254 return NT_STATUS_OK;
00255 }
00256
00257 static struct idmap_methods rid_methods = {
00258 .init = idmap_rid_initialize,
00259 .unixids_to_sids = idmap_rid_unixids_to_sids,
00260 .sids_to_unixids = idmap_rid_sids_to_unixids,
00261 .close_fn = idmap_rid_close
00262 };
00263
00264 NTSTATUS idmap_rid_init(void)
00265 {
00266 return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, "rid", &rid_methods);
00267 }
00268