/* Convert a Unix uid to a Windows SID, allocating a SID if needed */ wbcErr wbcUidToSid(uid_t uid, struct wbcDomainSid *sid) { int ret; char *str_sid; enum sss_id_type type; wbcErr wbc_status; ret = sss_nss_getsidbyid(uid, &str_sid, &type); if (ret != 0) { return WBC_ERR_UNKNOWN_FAILURE; } if (type != SSS_ID_TYPE_UID && type != SSS_ID_TYPE_BOTH) { free(str_sid); return WBC_ERR_UNKNOWN_USER; } wbc_status = wbcStringToSid(str_sid, sid); free(str_sid); if (!WBC_ERROR_IS_OK(wbc_status)) { return wbc_status; } return WBC_ERR_SUCCESS; }
int cifs_idmap_ids_to_sids(void *handle, const struct cifs_uxid *cuxid, const size_t num, struct cifs_sid *csid) { struct sssd_ctx *ctx = handle; int err, success = -1; char *sid; enum sss_id_type id_type; size_t i; debug("num ids: %zd", num); if (num > UINT_MAX) { ctx_set_error(ctx, "num is too large."); return EINVAL; } for (i = 0; i < num; ++i) { switch (cuxid[i].type) { case CIFS_UXID_TYPE_UID: err = sss_nss_getsidbyuid((uint32_t)cuxid[i].id.uid, &sid, &id_type); break; case CIFS_UXID_TYPE_GID: err = sss_nss_getsidbygid((uint32_t)cuxid[i].id.gid, &sid, &id_type); break; default: err = sss_nss_getsidbyid((uint32_t)cuxid[i].id.uid, &sid, &id_type); } if (err != 0) { ctx_set_error(ctx, strerror(err)); csid[i].revision = 0; /* FIXME: would it be safe to map *any* uid/gids unknown by sssd to * SAMBA's UNIX SIDs? */ continue; } if (sid_to_cifs_sid(ctx, sid, csid) == 0) success = 0; else csid[i].revision = 0; free(sid); } return success; }
int handle_request(struct ipa_extdom_ctx *ctx, struct extdom_req *req, struct extdom_res **res) { int ret; char *domain_name = NULL; char *sid_str = NULL; size_t buf_len; char *buf = NULL; long pw_max; long gr_max; struct pwd_grp pg_data; struct passwd *pwd_result = NULL; struct group *grp_result = NULL; enum sss_id_type id_type; char *fq_name = NULL; char *sep; pw_max = sysconf(_SC_GETPW_R_SIZE_MAX); gr_max = sysconf(_SC_GETGR_R_SIZE_MAX); if (pw_max == -1 && gr_max == -1) { buf_len = 16384; } else { buf_len = MAX(pw_max, gr_max); } buf = malloc(sizeof(char) * buf_len); if (buf == NULL) { return LDAP_OPERATIONS_ERROR; } switch (req->input_type) { case INP_POSIX_UID: if (req->request_type == REQ_SIMPLE) { ret = sss_nss_getsidbyid(req->data.posix_uid.uid, &sid_str, &id_type); } else { id_type = SSS_ID_TYPE_UID; ret = getpwuid_r(req->data.posix_uid.uid, &pg_data.data.pwd, buf, buf_len, &pwd_result); } domain_name = strdup(req->data.posix_uid.domain_name); break; case INP_POSIX_GID: if (req->request_type == REQ_SIMPLE) { ret = sss_nss_getsidbyid(req->data.posix_uid.uid, &sid_str, &id_type); } else { id_type = SSS_ID_TYPE_GID; ret = getgrgid_r(req->data.posix_gid.gid, &pg_data.data.grp, buf, buf_len, &grp_result); } domain_name = strdup(req->data.posix_gid.domain_name); break; case INP_SID: ret = sss_nss_getnamebysid(req->data.sid, &fq_name, &id_type); if (ret != 0) { ret = LDAP_OPERATIONS_ERROR; goto done; } sep = strrchr(fq_name, SSSD_DOMAIN_SEPARATOR); if (sep == NULL) { ret = LDAP_OPERATIONS_ERROR; goto done; } ret = asprintf(&domain_name, "%s", sep+1); if (ret == -1) { ret = LDAP_OPERATIONS_ERROR; domain_name = NULL; /* content is undefined according to asprintf(3) */ goto done; } switch(id_type) { case SSS_ID_TYPE_UID: case SSS_ID_TYPE_BOTH: ret = getpwnam_r(fq_name, &pg_data.data.pwd, buf, buf_len, &pwd_result); break; case SSS_ID_TYPE_GID: ret = getgrnam_r(fq_name, &pg_data.data.grp, buf, buf_len, &grp_result); break; default: ret = LDAP_OPERATIONS_ERROR; goto done; } break; case INP_NAME: ret = asprintf(&fq_name, "%s%c%s", req->data.name.object_name, SSSD_DOMAIN_SEPARATOR, req->data.name.domain_name); if (ret == -1) { ret = LDAP_OPERATIONS_ERROR; fq_name = NULL; /* content is undefined according to asprintf(3) */ goto done; } if (req->request_type == REQ_SIMPLE) { ret = sss_nss_getsidbyname(fq_name, &sid_str, &id_type); } else { id_type = SSS_ID_TYPE_UID; ret = getpwnam_r(fq_name, &pg_data.data.pwd, buf, buf_len, &pwd_result); if (ret == 0 && pwd_result == NULL) { /* no user entry found */ id_type = SSS_ID_TYPE_GID; ret = getgrnam_r(fq_name, &pg_data.data.grp, buf, buf_len, &grp_result); } } domain_name = strdup(req->data.name.domain_name); break; default: ret = LDAP_PROTOCOL_ERROR; goto done; } if (ret != 0) { ret = LDAP_OPERATIONS_ERROR; goto done; } else if (ret == 0 && pwd_result == NULL && grp_result == NULL && sid_str == NULL) { ret = LDAP_NO_SUCH_OBJECT; goto done; } if (domain_name == NULL) { ret = LDAP_OPERATIONS_ERROR; goto done; } ret = create_response(req, &pg_data, sid_str, id_type, domain_name, res); if (ret != 0) { ret = LDAP_OPERATIONS_ERROR; goto done; } ret = LDAP_SUCCESS; done: free(buf); free(fq_name); free(domain_name); free(sid_str); return ret; }